diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 2c48f945546b..5c86fe95555a 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -176,7 +176,6 @@ read the file /proc/PID/status: CapBnd: ffffffffffffffff voluntary_ctxt_switches: 0 nonvoluntary_ctxt_switches: 1 - Stack usage: 12 kB This shows you nearly the same information you would get if you viewed it with the ps command. In fact, ps uses the proc file system to obtain its @@ -230,7 +229,6 @@ Table 1-2: Contents of the statm files (as of 2.6.30-rc7) Mems_allowed_list Same as previous, but in "list format" voluntary_ctxt_switches number of voluntary context switches nonvoluntary_ctxt_switches number of non voluntary context switches - Stack usage: stack usage high water mark (round up to page size) .............................................................................. Table 1-3: Contents of the statm files (as of 2.6.8-rc3) @@ -309,7 +307,7 @@ address perms offset dev inode pathname 08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test 0804a000-0806b000 rw-p 00000000 00:00 0 [heap] a7cb1000-a7cb2000 ---p 00000000 00:00 0 -a7cb2000-a7eb2000 rw-p 00000000 00:00 0 [threadstack:001ff4b4] +a7cb2000-a7eb2000 rw-p 00000000 00:00 0 a7eb2000-a7eb3000 ---p 00000000 00:00 0 a7eb3000-a7ed5000 rw-p 00000000 00:00 0 a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6 @@ -345,7 +343,6 @@ is not associated with a file: [stack] = the stack of the main process [vdso] = the "virtual dynamic shared object", the kernel system call handler - [threadstack:xxxxxxxx] = the stack of the thread, xxxxxxxx is the stack size or if empty, the mapping is anonymous. diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index 3015da0c6b2a..fe09a2cb1858 100644 --- a/Documentation/filesystems/tmpfs.txt +++ b/Documentation/filesystems/tmpfs.txt @@ -82,11 +82,13 @@ tmpfs has a mount option to set the NUMA memory allocation policy for all files in that instance (if CONFIG_NUMA is enabled) - which can be adjusted on the fly via 'mount -o remount ...' -mpol=default prefers to allocate memory from the local node +mpol=default use the process allocation policy + (see set_mempolicy(2)) mpol=prefer:Node prefers to allocate memory from the given Node mpol=bind:NodeList allocates memory only from nodes in NodeList mpol=interleave prefers to allocate from each node in turn mpol=interleave:NodeList allocates from each node of NodeList in turn +mpol=local prefers to allocate memory from the local node NodeList format is a comma-separated list of decimal numbers and ranges, a range being two hyphen-separated decimal numbers, the smallest and @@ -134,3 +136,5 @@ Author: Christoph Rohland , 1.12.01 Updated: Hugh Dickins, 4 June 2007 +Updated: + KOSAKI Motohiro, 16 Mar 2010 diff --git a/Documentation/hwmon/ltc4245 b/Documentation/hwmon/ltc4245 index 02838a47d862..86b5880d8502 100644 --- a/Documentation/hwmon/ltc4245 +++ b/Documentation/hwmon/ltc4245 @@ -72,9 +72,7 @@ in6_min_alarm 5v output undervoltage alarm in7_min_alarm 3v output undervoltage alarm in8_min_alarm Vee (-12v) output undervoltage alarm -in9_input GPIO #1 voltage data -in10_input GPIO #2 voltage data -in11_input GPIO #3 voltage data +in9_input GPIO voltage data power1_input 12v power usage (mW) power2_input 5v power usage (mW) diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 81c0c59a60ea..e1bb5b261693 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 @@ -15,7 +15,8 @@ Supported adapters: * Intel 82801I (ICH9) * Intel EP80579 (Tolapai) * Intel 82801JI (ICH10) - * Intel PCH + * Intel 3400/5 Series (PCH) + * Intel Cougar Point (PCH) Datasheets: Publicly available at the Intel website Authors: diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5bc4eaaa5b7f..5f6aa11fb457 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -241,7 +241,7 @@ and is between 256 and 4096 characters. It is defined in the file acpi_sleep= [HW,ACPI] Sleep options Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, - old_ordering, s4_nonvs } + old_ordering, s4_nonvs, sci_force_enable } See Documentation/power/video.txt for information on s3_bios and s3_mode. s3_beep is for debugging; it makes the PC's speaker beep @@ -254,6 +254,9 @@ and is between 256 and 4096 characters. It is defined in the file of _PTS is used by default). s4_nonvs prevents the kernel from saving/restoring the ACPI NVS memory during hibernation. + sci_force_enable causes the kernel to set SCI_EN directly + on resume from S1/S3 (which is against the ACPI spec, + but some broken systems don't work without it). acpi_use_timer_override [HW,ACPI] Use timer override. For some broken Nvidia NF5 boards @@ -2668,6 +2671,13 @@ and is between 256 and 4096 characters. It is defined in the file medium is write-protected). Example: quirks=0419:aaf5:rl,0421:0433:rc + userpte= + [X86] Flags controlling user PTE allocations. + + nohigh = do not allocate PTE pages in + HIGHMEM regardless of setting + of CONFIG_HIGHPTE. + vdso= [X86,SH] vdso=2: enable compat VDSO (default with COMPAT_VDSO) vdso=1: enable VDSO (default) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index aafcaa634191..387eb9c6bf5d 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -460,6 +460,8 @@ event code Key Notes For Lenovo ThinkPads with a new BIOS, it has to be handled either by the ACPI OSI, or by userspace. + The driver does the right thing, + never mess with this. 0x1011 0x10 FN+END Brightness down. See brightness up for details. @@ -582,46 +584,15 @@ with hotkey_report_mode. Brightness hotkey notes: -These are the current sane choices for brightness key mapping in -thinkpad-acpi: +Don't mess with the brightness hotkeys in a Thinkpad. If you want +notifications for OSD, use the sysfs backlight class event support. -For IBM and Lenovo models *without* ACPI backlight control (the ones on -which thinkpad-acpi will autoload its backlight interface by default, -and on which ACPI video does not export a backlight interface): - -1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as - these older firmware versions unfortunately won't respect the hotkey - mask for brightness keys anyway, and always reacts to them. This - usually work fine, unless X.org drivers are doing something to block - the BIOS. In that case, use (3) below. This is the default mode of - operation. - -2. Enable the hotkeys, but map them to something else that is NOT - KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause - userspace to try to change the backlight level, and use that as an - on-screen-display hint. - -3. IF AND ONLY IF X.org drivers find a way to block the firmware from - automatically changing the brightness, enable the hotkeys and map - them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to - something that calls xbacklight. thinkpad-acpi will not be able to - change brightness in that case either, so you should disable its - backlight interface. - -For Lenovo models *with* ACPI backlight control: - -1. Load up ACPI video and use that. ACPI video will report ACPI - events for brightness change keys. Do not mess with thinkpad-acpi - defaults in this case. thinkpad-acpi should not have anything to do - with backlight events in a scenario where ACPI video is loaded: - brightness hotkeys must be disabled, and the backlight interface is - to be kept disabled as well. This is the default mode of operation. - -2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi, - and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process - these keys on userspace somehow (e.g. by calling xbacklight). - The driver will do this automatically if it detects that ACPI video - has been disabled. +The driver will issue KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN events +automatically for the cases were userspace has to do something to +implement brightness changes. When you override these events, you will +either fail to handle properly the ThinkPads that require explicit +action to change backlight brightness, or the ThinkPads that require +that no action be taken to work properly. Bluetooth @@ -679,6 +650,10 @@ LCD, CRT or DVI (if available). The following commands are available: echo expand_toggle > /proc/acpi/ibm/video echo video_switch > /proc/acpi/ibm/video +NOTE: Access to this feature is restricted to processes owning the +CAP_SYS_ADMIN capability for safety reasons, as it can interact badly +enough with some versions of X.org to crash it. + Each video output device can be enabled or disabled individually. Reading /proc/acpi/ibm/video shows the status of each device. @@ -1465,3 +1440,5 @@ Sysfs interface changelog: and it is always able to disable hot keys. Very old thinkpads are properly supported. hotkey_bios_mask is deprecated and marked for removal. + +0x020600: Marker for backlight change event support. diff --git a/Documentation/networking/3c509.txt b/Documentation/networking/3c509.txt index 0643e3b7168c..3c45d5dcd63b 100644 --- a/Documentation/networking/3c509.txt +++ b/Documentation/networking/3c509.txt @@ -48,11 +48,11 @@ for LILO parameters for doing this: This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts with other card types when overriding the I/O address. When the driver is -loaded as a module, only the IRQ and transceiver setting may be overridden. -For example, setting two cards to 10base2/IRQ10 and AUI/IRQ11 is done by using -the xcvr and irq module options: +loaded as a module, only the IRQ may be overridden. For example, +setting two cards to IRQ10 and IRQ11 is done by using the irq module +option: - options 3c509 xcvr=3,1 irq=10,11 + options 3c509 irq=10,11 (2) Full-duplex mode @@ -77,6 +77,8 @@ operation. itself full-duplex capable. This is almost certainly one of two things: a full- duplex-capable Ethernet switch (*not* a hub), or a full-duplex-capable NIC on another system that's connected directly to the 3c509B via a crossover cable. + +Full-duplex mode can be enabled using 'ethtool'. /////Extremely important caution concerning full-duplex mode///// Understand that the 3c509B's hardware's full-duplex support is much more @@ -113,6 +115,8 @@ This insured that merely upgrading the driver from an earlier version would never automatically enable full-duplex mode in an existing installation; it must always be explicitly enabled via one of these code in order to be activated. + +The transceiver type can be changed using 'ethtool'. (4a) Interpretation of error messages and common problems diff --git a/MAINTAINERS b/MAINTAINERS index c57d3964e00c..b23a092ee64b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1974,6 +1974,12 @@ W: http://acpi4asus.sf.net S: Maintained F: drivers/platform/x86/eeepc-laptop.c +EFIFB FRAMEBUFFER DRIVER +L: linux-fbdev@vger.kernel.org +M: Peter Jones +S: Maintained +F: drivers/video/efifb.c + EFS FILESYSTEM W: http://aeschi.ch.eu.org/efs/ S: Orphan diff --git a/Makefile b/Makefile index d7cf5448ee7b..7be29d6c48cd 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 32 -EXTRAVERSION = .9 +EXTRAVERSION = .27 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* @@ -1596,3 +1596,7 @@ FORCE: # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable so we can use it in if_changed and friends. .PHONY: $(PHONY) + + +%.o: %.uu prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) diff --git a/arch/Kconfig b/arch/Kconfig index 7f418bbc261a..90934b97acd5 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -6,8 +6,6 @@ config OPROFILE tristate "OProfile system profiling (EXPERIMENTAL)" depends on PROFILING depends on HAVE_OPROFILE - depends on TRACING_SUPPORT - select TRACING select RING_BUFFER select RING_BUFFER_ALLOW_SWAP help diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index 52a79dfc13c6..5c905aaaeccd 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c @@ -109,7 +109,7 @@ marvel_print_err_cyc(u64 err_cyc) #define IO7__ERR_CYC__CYCLE__M (0x7) printk("%s Packet In Error: %s\n" - "%s Error in %s, cycle %ld%s%s\n", + "%s Error in %s, cycle %lld%s%s\n", err_print_prefix, packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)], err_print_prefix, @@ -313,7 +313,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym) } printk("%s Up Hose Garbage Symptom:\n" - "%s Source Port: %ld - Dest PID: %ld - OpCode: %s\n", + "%s Source Port: %lld - Dest PID: %lld - OpCode: %s\n", err_print_prefix, err_print_prefix, EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT), @@ -552,7 +552,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff) printk("%s Split Completion Error:\n" - "%s Source (Bus:Dev:Func): %ld:%ld:%ld\n", + "%s Source (Bus:Dev:Func): %lld:%lld:%lld\n", err_print_prefix, err_print_prefix, EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS), diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5aa36c4f303e..02b744803efe 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -722,10 +722,11 @@ config ARCH_RK29 select CPU_V7 select HAVE_CLK select COMMON_CLKDEV + select ARCH_HAS_CPUFREQ select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB - select ARM_GIC + select ARM_GIC help Support for Rockchip RK29 soc. @@ -918,6 +919,18 @@ config ARM_ERRATA_460075 ACTLR register. Note that setting specific bits in the ACTLR register may not be available in non-secure mode. +config ARM_ERRATA_720789 + bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" + depends on CPU_V7 && SMP + help + This option enables the workaround for the 720789 Cortex-A9 (prior to + r2p0) erratum. A faulty ASID can be sent to the other CPUs for the + broadcasted CP15 TLB maintenance operations TLBIASIDIS and TLBIMVAIS. + As a consequence of this erratum, some TLB entries which should be + invalidated are not, resulting in an incoherency in the system page + tables. The workaround changes the TLB flushing routines to invalidate + entries regardless of the ASID. + endmenu source "arch/arm/common/Kconfig" diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index b5d44a069624..8d42f8ef9d4d 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -162,9 +162,9 @@ not_angel: .text adr r0, LC0 - ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} ) - THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, ip} ) - THUMB( ldr sp, [r0, #28] ) + ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp}) + THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} ) + THUMB( ldr sp, [r0, #32] ) subs r0, r0, r1 @ calculate the delta offset @ if delta is zero, we are @@ -174,12 +174,13 @@ not_angel: /* * We're running at a different address. We need to fix * up various pointers: - * r5 - zImage base address - * r6 - GOT start + * r5 - zImage base address (_start) + * r6 - size of decompressed image + * r11 - GOT start * ip - GOT end */ add r5, r5, r0 - add r6, r6, r0 + add r11, r11, r0 add ip, ip, r0 #ifndef CONFIG_ZBOOT_ROM @@ -197,10 +198,10 @@ not_angel: /* * Relocate all entries in the GOT table. */ -1: ldr r1, [r6, #0] @ relocate entries in the GOT +1: ldr r1, [r11, #0] @ relocate entries in the GOT add r1, r1, r0 @ table. This fixes up the - str r1, [r6], #4 @ C references. - cmp r6, ip + str r1, [r11], #4 @ C references. + cmp r11, ip blo 1b #else @@ -208,12 +209,12 @@ not_angel: * Relocate entries in the GOT table. We only relocate * the entries that are outside the (relocated) BSS region. */ -1: ldr r1, [r6, #0] @ relocate entries in the GOT +1: ldr r1, [r11, #0] @ relocate entries in the GOT cmp r1, r2 @ entry < bss_start || cmphs r3, r1 @ _end < entry addlo r1, r1, r0 @ table. This fixes up the - str r1, [r6], #4 @ C references. - cmp r6, ip + str r1, [r11], #4 @ C references. + cmp r11, ip blo 1b #endif @@ -239,6 +240,7 @@ not_relocated: mov r0, #0 * Check to see if we will overwrite ourselves. * r4 = final kernel address * r5 = start of this image + * r6 = size of decompressed image * r2 = end of malloc space (and therefore this image) * We basically want: * r4 >= r2 -> OK @@ -246,8 +248,7 @@ not_relocated: mov r0, #0 */ cmp r4, r2 bhs wont_overwrite - sub r3, sp, r5 @ > compressed kernel size - add r0, r4, r3, lsl #2 @ allow for 4x expansion + add r0, r4, r6 cmp r0, r5 bls wont_overwrite @@ -263,7 +264,6 @@ not_relocated: mov r0, #0 * r1-r3 = unused * r4 = kernel execution address * r5 = decompressed kernel start - * r6 = processor ID * r7 = architecture ID * r8 = atags pointer * r9-r12,r14 = corrupted @@ -304,7 +304,8 @@ LC0: .word LC0 @ r1 .word _end @ r3 .word zreladdr @ r4 .word _start @ r5 - .word _got_start @ r6 + .word _image_size @ r6 + .word _got_start @ r11 .word _got_end @ ip .word user_stack+4096 @ sp LC1: .word reloc_end - reloc_start @@ -328,7 +329,6 @@ params: ldr r0, =params_phys * * On entry, * r4 = kernel execution address - * r6 = processor ID * r7 = architecture number * r8 = atags pointer * r9 = run-time address of "start" (???) @@ -534,7 +534,6 @@ __common_mmu_cache_on: * r1-r3 = unused * r4 = kernel execution address * r5 = decompressed kernel start - * r6 = processor ID * r7 = architecture ID * r8 = atags pointer * r9-r12,r14 = corrupted @@ -573,19 +572,19 @@ call_kernel: bl cache_clean_flush * r1 = corrupted * r2 = corrupted * r3 = block offset - * r6 = corrupted + * r9 = corrupted * r12 = corrupted */ call_cache_fn: adr r12, proc_types #ifdef CONFIG_CPU_CP15 - mrc p15, 0, r6, c0, c0 @ get processor ID + mrc p15, 0, r9, c0, c0 @ get processor ID #else - ldr r6, =CONFIG_PROCESSOR_ID + ldr r9, =CONFIG_PROCESSOR_ID #endif 1: ldr r1, [r12, #0] @ get value ldr r2, [r12, #4] @ get mask - eor r1, r1, r6 @ (real ^ match) + eor r1, r1, r9 @ (real ^ match) tst r1, r2 @ & mask ARM( addeq pc, r12, r3 ) @ call cache function THUMB( addeq r12, r3 ) @@ -767,8 +766,7 @@ proc_types: * Turn off the Cache and MMU. ARMv3 does not support * reading the control register, but ARMv4 does. * - * On entry, r6 = processor ID - * On exit, r0, r1, r2, r3, r12 corrupted + * On exit, r0, r1, r2, r3, r9, r12 corrupted * This routine must preserve: r4, r6, r7 */ .align 5 @@ -841,10 +839,8 @@ __armv3_mmu_cache_off: /* * Clean and flush the cache to maintain consistency. * - * On entry, - * r6 = processor ID * On exit, - * r1, r2, r3, r11, r12 corrupted + * r1, r2, r3, r9, r11, r12 corrupted * This routine must preserve: * r0, r4, r5, r6, r7 */ @@ -956,7 +952,7 @@ __armv4_mmu_cache_flush: mov r2, #64*1024 @ default: 32K dcache size (*2) mov r11, #32 @ default: 32 byte line size mrc p15, 0, r3, c0, c0, 1 @ read cache type - teq r3, r6 @ cache ID register present? + teq r3, r9 @ cache ID register present? beq no_cache_id mov r1, r3, lsr #18 and r1, r1, #7 diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index a5924b9b88bd..cbed030b55cf 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in @@ -36,6 +36,9 @@ SECTIONS _etext = .; + /* Assume size of decompressed image is 4x the compressed image */ + _image_size = (_etext - _text) * 4; + _got_start = .; .got : { *(.got) } _got_end = .; diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 8ba7044c554d..b07bfee26e32 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -887,8 +887,6 @@ static int sa1111_resume(struct platform_device *dev) if (!save) return 0; - spin_lock_irqsave(&sachip->lock, flags); - /* * Ensure that the SA1111 is still here. * FIXME: shouldn't do this here. @@ -905,6 +903,13 @@ static int sa1111_resume(struct platform_device *dev) * First of all, wake up the chip. */ sa1111_wake(sachip); + + /* + * Only lock for write ops. Also, sa1111_wake must be called with + * released spinlock! + */ + spin_lock_irqsave(&sachip->lock, flags); + sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0); sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1); diff --git a/arch/arm/configs/rk29_sdk_defconfig b/arch/arm/configs/rk29_sdk_defconfig index ce584fd42771..839a760cbc0a 100755 --- a/arch/arm/configs/rk29_sdk_defconfig +++ b/arch/arm/configs/rk29_sdk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.32.9 -# Sat Dec 11 12:17:37 2010 +# Linux kernel version: 2.6.32.27 +# Sat Dec 18 09:08:43 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -16,6 +16,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y @@ -298,6 +299,21 @@ CONFIG_ATAGS_PROC=y # # CPU Power Management # +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=y +# 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 is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set # CONFIG_CPU_IDLE is not set # @@ -425,6 +441,10 @@ CONFIG_WIRELESS_EXT_SYSFS=y # # CFG80211 needs to be enabled for MAC80211 # + +# +# Some wireless drivers require a rate control algorithm +# # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -515,6 +535,7 @@ CONFIG_MTD_NAND_IDS=y CONFIG_MTD_RKNAND=y CONFIG_MTD_NAND_RK29XX=y CONFIG_RKFTL_PAGECACHE_SIZE=64 +CONFIG_MTD_RKNAND_BUFFER=y # CONFIG_MTD_NAND_RK29XX_DEBUG is not set # CONFIG_MTD_ONENAND is not set @@ -533,6 +554,7 @@ CONFIG_BLK_DEV=y 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 @@ -562,9 +584,42 @@ CONFIG_HAVE_IDE=y # SCSI device support # # CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA 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 +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_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y @@ -620,6 +675,7 @@ CONFIG_WLAN=y # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y # CONFIG_LIBERTAS is not set +# CONFIG_USB_ZD1201 is not set # CONFIG_HOSTAP is not set CONFIG_BCM4329=m CONFIG_BCM4329_FW_PATH="/etc/firmware/fw_bcm4329.bin" @@ -628,6 +684,15 @@ CONFIG_BCM4329_NVRAM_PATH="/etc/firmware/nvram_bcm4329_B23.txt" # # Enable WiMAX (Networking options) to see the WiMAX drivers # + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -695,6 +760,7 @@ CONFIG_TOUCHSCREEN_XPT2046_SPI_NOCHOOSE=y # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set # CONFIG_TOUCHSCREEN_W90X900 is not set @@ -863,8 +929,131 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set # CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=y + +# +# 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_CUSTOMISE 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_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF_DMA_CONTIG=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +CONFIG_SOC_CAMERA=y +# CONFIG_SOC_CAMERA_MT9M001 is not set +# CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_TW9910 is not set +# CONFIG_SOC_CAMERA_PLATFORM is not set +# CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV2655 is not set +CONFIG_SOC_CAMERA_OV2659=y +# CONFIG_SOC_CAMERA_OV9650 is not set +# CONFIG_SOC_CAMERA_OV3640 is not set +CONFIG_SOC_CAMERA_OV5642=y +CONFIG_OV5642_AUTOFOCUS=y +# CONFIG_OV5642_FIXEDFOCUS is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +CONFIG_VIDEO_RK29=y +CONFIG_VIDEO_RK29_WORK_ONEFRAME=y +# CONFIG_VIDEO_RK29_WORK_PINGPONG is not set +CONFIG_VIDEO_RK29_WORK_IPP=y +# CONFIG_VIDEO_RK29_WORK_NOT_IPP is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C20X 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_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C 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_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX 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_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_PWC_INPUT_EVDEV=y +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_I2C_SI4713 is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_RADIO_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_RADIO_TEA5764 is not set # CONFIG_SMS_SIANO_MDTV is not set +# CONFIG_DAB is not set # # Graphics support @@ -974,6 +1163,9 @@ CONFIG_SND_JACK=y # CONFIG_SND_EMU10K1_SEQ is not set # CONFIG_SND_DRIVERS is not set # CONFIG_SND_ARM is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set CONFIG_SND_SOC=y CONFIG_SND_RK29_SOC=y CONFIG_SND_RK29_SOC_I2S=y @@ -988,7 +1180,208 @@ CONFIG_SND_SOC_I2C_AND_SPI=y CONFIG_SND_SOC_WM8900=y # CONFIG_SOUND_PRIME is not set # CONFIG_HID_SUPPORT is not set -# CONFIG_USB_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# 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=y +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +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_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_EZUSB is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +CONFIG_USB_GADGET_DWC_OTG=y +CONFIG_USB_DWC_OTG=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_ANDROID=y +# CONFIG_USB_ANDROID_ACM is not set +CONFIG_USB_ANDROID_ADB=y +CONFIG_USB_ANDROID_MASS_STORAGE=y +# CONFIG_USB_ANDROID_RNDIS is not set +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB11_HOST=y +CONFIG_USB20_HOST=y +CONFIG_USB20_OTG=y +# CONFIG_DWC_OTG_HOST_ONLY is not set +CONFIG_DWC_OTG_DEVICE_ONLY=y +CONFIG_DWC_CONN_EN=y +# CONFIG_DWC_OTG_DEBUG is not set +CONFIG_DWC_OTG=y CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set @@ -1091,7 +1484,12 @@ CONFIG_RTC_HYM8563=y # CONFIG_STAGING=y # CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_USB_IP_COMMON is not set +# CONFIG_PRISM2_USB is not set # CONFIG_ECHO is not set +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_TRANZPORT is not set # # Android @@ -1121,6 +1519,11 @@ CONFIG_ANDROID_LOW_MEMORY_KILLER=y # CONFIG_DST is not set # CONFIG_POHMELFS is not set # CONFIG_PLAN9AUTH is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set +# CONFIG_VT6656 is not set +# CONFIG_FB_UDL is not set # # RAR Register Driver @@ -1148,6 +1551,11 @@ CONFIG_ANDROID_LOW_MEMORY_KILLER=y # CONFIG_VIVANTE=y +# +# IPP +# +CONFIG_RK29_IPP=y + # # CMMB # diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 00f46d9ce299..eea494790b56 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -215,7 +215,7 @@ @ Slightly optimised to avoid incrementing the pointer twice usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort .if \rept == 2 - usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort + usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort .endif add\cond \ptr, #\rept * \inc diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index bbecccda76d0..1df645713d48 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -150,15 +150,24 @@ struct pt_regs { */ static inline int valid_user_regs(struct pt_regs *regs) { - if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) { - regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); - return 1; + unsigned long mode = regs->ARM_cpsr & MODE_MASK; + + /* + * Always clear the F (FIQ) and A (delayed abort) bits + */ + regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); + + if ((regs->ARM_cpsr & PSR_I_BIT) == 0) { + if (mode == USR_MODE) + return 1; + if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE) + return 1; } /* * Force CPSR to something logical... */ - regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT; + regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT; if (!(elf_hwcap & HWCAP_26BIT)) regs->ARM_cpsr |= USR_MODE; diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index c2f1605de359..00c1cba729cb 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -369,7 +369,11 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) if (tlb_flag(TLB_V6_I_ASID)) asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); if (tlb_flag(TLB_V7_UIS_ASID)) +#ifdef CONFIG_ARM_ERRATA_720789 + asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); +#else asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); +#endif if (tlb_flag(TLB_BTB)) { /* flush the branch target cache */ @@ -409,7 +413,11 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) if (tlb_flag(TLB_V6_I_PAGE)) asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V7_UIS_PAGE)) +#ifdef CONFIG_ARM_ERRATA_720789 + asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc"); +#else asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); +#endif if (tlb_flag(TLB_BTB)) { /* flush the branch target cache */ diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 2c1db77d7848..a6c66f598d14 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -382,11 +382,13 @@ ENDPROC(sys_clone_wrapper) sys_sigreturn_wrapper: add r0, sp, #S_OFF + mov why, #0 @ prevent syscall restart handling b sys_sigreturn ENDPROC(sys_sigreturn_wrapper) sys_rt_sigreturn_wrapper: add r0, sp, #S_OFF + mov why, #0 @ prevent syscall restart handling b sys_rt_sigreturn ENDPROC(sys_rt_sigreturn_wrapper) diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index da1f94906a4e..8bccbfa693ff 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c @@ -583,13 +583,14 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) { insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0]; kprobe_opcode_t insn = p->opcode; + long ppc = (long)p->addr + 8; union reg_pair fnr; int rd = (insn >> 12) & 0xf; int rn = (insn >> 16) & 0xf; int rm = insn & 0xf; long rdv; - long rnv = regs->uregs[rn]; - long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ + long rnv = (rn == 15) ? ppc : regs->uregs[rn]; + long rmv = (rm == 15) ? ppc : regs->uregs[rm]; long cpsr = regs->ARM_cpsr; fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn); diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S index 1e4cbd4e7be9..64f6bc1a9132 100644 --- a/arch/arm/lib/findbit.S +++ b/arch/arm/lib/findbit.S @@ -174,8 +174,8 @@ ENDPROC(_find_next_bit_be) */ .L_found: #if __LINUX_ARM_ARCH__ >= 5 - rsb r1, r3, #0 - and r3, r3, r1 + rsb r0, r3, #0 + and r3, r3, r0 clz r3, r3 rsb r3, r3, #31 add r0, r2, r3 @@ -190,5 +190,7 @@ ENDPROC(_find_next_bit_be) addeq r2, r2, #1 mov r0, r2 #endif + cmp r1, r0 @ Clamp to maxbit + movlo r0, r1 mov pc, lr diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 332b784050b2..2f7e4980a1d8 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -46,7 +46,7 @@ static struct resource hdmac_resources[] = { .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, .flags = IORESOURCE_MEM, }, - [2] = { + [1] = { .start = AT91SAM9G45_ID_DMA, .end = AT91SAM9G45_ID_DMA, .flags = IORESOURCE_IRQ, diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index e34d96a825e3..6879cfec2c7b 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -37,6 +37,10 @@ #define SYSTEM_REV_S_USES_VAUX3 0x8 static int board_keymap[] = { + /* + * Note that KEY(x, 8, KEY_XXX) entries represent "entrire row + * connected to the ground" matrix state. + */ KEY(0, 0, KEY_Q), KEY(0, 1, KEY_O), KEY(0, 2, KEY_P), @@ -44,6 +48,7 @@ static int board_keymap[] = { KEY(0, 4, KEY_BACKSPACE), KEY(0, 6, KEY_A), KEY(0, 7, KEY_S), + KEY(1, 0, KEY_W), KEY(1, 1, KEY_D), KEY(1, 2, KEY_F), @@ -52,6 +57,7 @@ static int board_keymap[] = { KEY(1, 5, KEY_J), KEY(1, 6, KEY_K), KEY(1, 7, KEY_L), + KEY(2, 0, KEY_E), KEY(2, 1, KEY_DOT), KEY(2, 2, KEY_UP), @@ -59,6 +65,8 @@ static int board_keymap[] = { KEY(2, 5, KEY_Z), KEY(2, 6, KEY_X), KEY(2, 7, KEY_C), + KEY(2, 8, KEY_F9), + KEY(3, 0, KEY_R), KEY(3, 1, KEY_V), KEY(3, 2, KEY_B), @@ -67,20 +75,23 @@ static int board_keymap[] = { KEY(3, 5, KEY_SPACE), KEY(3, 6, KEY_SPACE), KEY(3, 7, KEY_LEFT), + KEY(4, 0, KEY_T), KEY(4, 1, KEY_DOWN), KEY(4, 2, KEY_RIGHT), KEY(4, 4, KEY_LEFTCTRL), KEY(4, 5, KEY_RIGHTALT), KEY(4, 6, KEY_LEFTSHIFT), + KEY(4, 8, KEY_F10), + KEY(5, 0, KEY_Y), + KEY(5, 8, KEY_F11), + KEY(6, 0, KEY_U), + KEY(7, 0, KEY_I), KEY(7, 1, KEY_F7), KEY(7, 2, KEY_F8), - KEY(0xff, 2, KEY_F9), - KEY(0xff, 4, KEY_F10), - KEY(0xff, 5, KEY_F11), }; static struct matrix_keymap_data board_map_data = { diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h index 811743c56147..5f2ba8d9015c 100644 --- a/arch/arm/mach-pxa/include/mach/colibri.h +++ b/arch/arm/mach-pxa/include/mach/colibri.h @@ -2,6 +2,7 @@ #define _COLIBRI_H_ #include +#include /* * common settings for all modules diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index c48e1f2c3349..6727c783e0d6 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig @@ -18,6 +18,7 @@ config REALVIEW_EB_ARM11MP bool "Support ARM11MPCore tile" depends on MACH_REALVIEW_EB select CPU_V6 + select ARCH_HAS_BARRIERS if SMP help Enable support for the ARM11MPCore tile on the Realview platform. @@ -35,6 +36,7 @@ config MACH_REALVIEW_PB11MP select CPU_V6 select ARM_GIC select HAVE_PATA_PLATFORM + select ARCH_HAS_BARRIERS if SMP help Include support for the ARM(R) RealView MPCore Platform Baseboard. PB11MPCore is a platform with an on-board ARM11MPCore and has diff --git a/arch/arm/mach-realview/include/mach/barriers.h b/arch/arm/mach-realview/include/mach/barriers.h new file mode 100644 index 000000000000..0c5d749d7b5f --- /dev/null +++ b/arch/arm/mach-realview/include/mach/barriers.h @@ -0,0 +1,8 @@ +/* + * Barriers redefined for RealView ARM11MPCore platforms with L220 cache + * controller to work around hardware errata causing the outer_sync() + * operation to deadlock the system. + */ +#define mb() dsb() +#define rmb() dmb() +#define wmb() mb() diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 0b29186672f9..e63176f2d450 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -60,14 +60,20 @@ #define PMEM_GPU_SIZE SZ_64M #define PMEM_UI_SIZE SZ_32M #define PMEM_VPU_SIZE SZ_32M -#define PMEM_CAM_SIZE SZ_16M +#define PMEM_CAM_SIZE 0x00c00000 +#ifdef CONFIG_VIDEO_RK29_WORK_IPP +#define MEM_CAMIPP_SIZE SZ_4M +#else +#define MEM_CAMIPP_SIZE 0 +#endif #define MEM_FB_SIZE (3*SZ_2M) #define PMEM_GPU_BASE ((u32)RK29_SDRAM_PHYS + SDRAM_SIZE - PMEM_GPU_SIZE) #define PMEM_UI_BASE (PMEM_GPU_BASE - PMEM_UI_SIZE) #define PMEM_VPU_BASE (PMEM_UI_BASE - PMEM_VPU_SIZE) #define PMEM_CAM_BASE (PMEM_VPU_BASE - PMEM_CAM_SIZE) -#define MEM_FB_BASE (PMEM_CAM_BASE - MEM_FB_SIZE) +#define MEM_CAMIPP_BASE (PMEM_CAM_BASE - MEM_CAMIPP_SIZE) +#define MEM_FB_BASE (MEM_CAMIPP_BASE - MEM_FB_SIZE) #define LINUX_SIZE (MEM_FB_BASE - RK29_SDRAM_PHYS) extern struct sys_timer rk29_timer; @@ -577,7 +583,14 @@ struct rk29camera_platform_data rk29_camera_platform_data = { .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_1|SENSOR_RESETACTIVE_LEVEL_1), .dev_name = SENSOR_NAME_1, } - } + }, + #ifdef CONFIG_VIDEO_RK29_WORK_IPP + .meminfo = { + .name = "camera_ipp_mem", + .start = MEM_CAMIPP_BASE, + .size = MEM_CAMIPP_SIZE, + } + #endif }; static int rk29_sensor_io_init(void) @@ -737,7 +750,32 @@ struct platform_device rk29_soc_camera_pdrv_1 = { }; -extern struct platform_device rk29_device_camera; +static u64 rockchip_device_camera_dmamask = 0xffffffffUL; +struct resource rk29_camera_resource[] = { + [0] = { + .start = RK29_VIP_PHYS, + .end = RK29_VIP_PHYS + RK29_VIP_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_VIP, + .end = IRQ_VIP, + .flags = IORESOURCE_IRQ, + } +}; + +/*platform_device : */ +struct platform_device rk29_device_camera = { + .name = RK29_CAM_DRV_NAME, + .id = RK29_CAM_PLATFORM_DEV_ID, /* This is used to put cameras on this interface */ + .num_resources = ARRAY_SIZE(rk29_camera_resource), + .resource = rk29_camera_resource, + .dev = { + .dma_mask = &rockchip_device_camera_dmamask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &rk29_camera_platform_data, + } +}; #endif /***************************************************************************************** * backlight devices @@ -1032,13 +1070,6 @@ static struct platform_device rk29_device_keys = { }, }; #endif -/********************usb*********************/ -struct usb_mass_storage_platform_data mass_storage_pdata = { - .nluns = 1, - .vendor = "RockChip", - .product = "rk9 sdk", - .release = 0x0100, -}; static void __init rk29_board_iomux_init(void) { @@ -1171,13 +1202,22 @@ static struct platform_device *devices[] __initdata = { #endif &android_pmem_device, &rk29_vpu_mem_device, -#ifdef CONFIG_DWC_OTG - &rk29_device_dwc_otg, +#ifdef CONFIG_USB20_OTG + &rk29_device_usb20_otg, +#endif +#ifdef CONFIG_USB20_HOST + &rk29_device_usb20_host, +#endif +#ifdef CONFIG_USB11_HOST + &rk29_device_usb11_host, #endif #ifdef CONFIG_USB_ANDROID &android_usb_device, &usb_mass_storage_device, #endif +#ifdef CONFIG_RK29_IPP + &rk29_device_ipp, +#endif }; /***************************************************************************************** diff --git a/arch/arm/mach-rk29/clock.c b/arch/arm/mach-rk29/clock.c index 02c1a06bc447..771f8215c20b 100755 --- a/arch/arm/mach-rk29/clock.c +++ b/arch/arm/mach-rk29/clock.c @@ -31,6 +31,13 @@ #include #include + +#define PWM_VCORE_120 40 +#define PWM_VCORE_125 32 +#define PWM_VCORE_130 21 +#define PWM_VCORE_135 10 +#define PWM_VCORE_140 0 + /* CRU PLL CON */ #define PLL_HIGH_BAND (0x01 << 16) #define PLL_LOW_BAND (0x00 << 16) @@ -360,11 +367,11 @@ static const struct arm_pll_set arm_pll[] = { ARM_PLL(1152, 1, 48, 1, 41, 21, 81), ARM_PLL(1104, 1, 46, 1, 41, 21, 81), ARM_PLL(1056, 1, 44, 1, 41, 21, 81), - ARM_PLL(1008, 1, 42, 1, 31, 21, 81), - ARM_PLL( 960, 1, 40, 1, 31, 21, 81), - ARM_PLL( 912, 1, 38, 1, 31, 21, 81), + ARM_PLL(1008, 1, 42, 1, 41, 21, 81), + ARM_PLL( 960, 1, 40, 1, 41, 21, 81), + ARM_PLL( 912, 1, 38, 1, 41, 21, 81), ARM_PLL( 888, 2, 74, 1, 31, 21, 81), - ARM_PLL( 624, 1, 52, 2, 21, 21, 81), + ARM_PLL( 624, 1, 52, 2, 31, 21, 81), // last item, pll power down. ARM_PLL( 24, 1, 64, 8, 21, 21, 41), }; @@ -462,7 +469,7 @@ static int arm_pll_clk_set_rate(struct clk *clk, unsigned long rate) pt++; } - PWMInit(1 * MHZ, 0); // 1.4V + PWMInit(1 * MHZ, PWM_VCORE_135); // 1.35V /* make aclk safe & reparent to periph pll */ cru_writel((cru_readl(CRU_CLKSEL0_CON) & ~(CORE_PARENT_MASK | CORE_ACLK_MASK)) | CORE_PARENT_PERIPH_PLL | CORE_ACLK_21, CRU_CLKSEL0_CON); @@ -2257,9 +2264,9 @@ static void rk29_clock_common_init(void) /* periph pll */ clk_set_rate_nolock(&periph_pll_clk, 624 * MHZ); clk_set_parent_nolock(&aclk_periph, &periph_pll_clk); - clk_set_rate_nolock(&aclk_periph, 312 * MHZ); - clk_set_rate_nolock(&hclk_periph, 156 * MHZ); - clk_set_rate_nolock(&pclk_periph, 78 * MHZ); + clk_set_rate_nolock(&aclk_periph, 208 * MHZ); + clk_set_rate_nolock(&hclk_periph, 104 * MHZ); + clk_set_rate_nolock(&pclk_periph, 52 * MHZ); clk_set_parent_nolock(&clk_uhost, &periph_pll_clk); clk_set_rate_nolock(&clk_uhost, 48 * MHZ); clk_set_parent_nolock(&clk_i2s0_div, &periph_pll_clk); diff --git a/arch/arm/mach-rk29/devices.c b/arch/arm/mach-rk29/devices.c index a4d50aa90f81..b66ea3a37279 100755 --- a/arch/arm/mach-rk29/devices.c +++ b/arch/arm/mach-rk29/devices.c @@ -404,39 +404,6 @@ struct platform_device rk29xx_device_spi1m = { }, }; -/* RK29 Camera : ddl@rock-chips.com */ -#ifdef CONFIG_VIDEO_RK29 -extern struct rk29camera_platform_data rk29_camera_platform_data; - -static struct resource rk29_camera_resource[] = { - [0] = { - .start = RK29_VIP_PHYS, - .end = RK29_VIP_PHYS + RK29_VIP_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_VIP, - .end = IRQ_VIP, - .flags = IORESOURCE_IRQ, - } -}; - -static u64 rockchip_device_camera_dmamask = 0xffffffffUL; - -/*platform_device : */ -struct platform_device rk29_device_camera = { - .name = RK29_CAM_DRV_NAME, - .id = RK29_CAM_PLATFORM_DEV_ID, /* This is used to put cameras on this interface */ - .num_resources = ARRAY_SIZE(rk29_camera_resource), - .resource = rk29_camera_resource, - .dev = { - .dma_mask = &rockchip_device_camera_dmamask, - .coherent_dma_mask = 0xffffffffUL, - .platform_data = &rk29_camera_platform_data, - } -}; -#endif - #if defined(CONFIG_MTD_NAND_RK29XX) static struct resource rk29xxnand_resources[] = { { @@ -541,9 +508,34 @@ struct platform_device rk29_device_iis_8ch = { .resource = rk29_iis_8ch_resource, }; #endif -#ifdef CONFIG_DWC_OTG +#ifdef CONFIG_RK29_IPP +/* rk29 ipp resource */ +static struct resource rk29_ipp_resource[] = { + [0] = { + .start = RK29_IPP_PHYS, + .end = RK29_IPP_PHYS + RK29_IPP_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IPP, + .end = IRQ_IPP, + .flags = IORESOURCE_IRQ, + }, +}; + +/*platform_device*/ +//extern struct rk29ipp_info rk29_ipp_info; +struct platform_device rk29_device_ipp = { + .name = "rk29-ipp", + .id = -1, + .num_resources = ARRAY_SIZE(rk29_ipp_resource), + .resource = rk29_ipp_resource, +}; +#endif + +#ifdef CONFIG_USB20_OTG /*DWC_OTG*/ -static struct resource dwc_otg_resource[] = { +static struct resource usb20_otg_resource[] = { { .start = IRQ_USB_OTG0, .end = IRQ_USB_OTG0, @@ -557,12 +549,14 @@ static struct resource dwc_otg_resource[] = { }; -struct platform_device rk29_device_dwc_otg = { - .name = "dwc_otg", +struct platform_device rk29_device_usb20_otg = { + .name = "usb20_otg", .id = -1, - .num_resources = ARRAY_SIZE(dwc_otg_resource), - .resource = dwc_otg_resource, + .num_resources = ARRAY_SIZE(usb20_otg_resource), + .resource = usb20_otg_resource, }; +#endif +#ifdef CONFIG_USB_ANDROID static char *usb_functions_rockchip[] = { "usb_mass_storage", @@ -615,7 +609,7 @@ static struct android_usb_product usb_products[] = { .functions = usb_functions_rockchip, }, { - .product_id = 0x4e12, + .product_id = 0x2810,//0x0c02,//0x4e12, .num_functions = ARRAY_SIZE(usb_functions_rockchip_adb), .functions = usb_functions_rockchip_adb, }, @@ -637,7 +631,10 @@ static struct android_usb_product usb_products[] = { }, #endif }; - +/* + * if anyone want to use adb driver of HTC G1, + * please change vendor_id to 0x0bb4 and product_id to 0x0c02. + */ static struct android_usb_platform_data android_usb_pdata = { .vendor_id = 0x2207,//0x0bb4,//0x18d1, .product_id = 0x2810,//0x4e11, @@ -659,6 +656,14 @@ struct platform_device android_usb_device = { }, }; +/********************usb*********************/ +struct usb_mass_storage_platform_data mass_storage_pdata = { + .nluns = 1, + .vendor = "RockChip", + .product = "rk29 sdk", + .release = 0x0100, +}; + //static struct platform_device usb_mass_storage_device = { .name = "usb_mass_storage", @@ -668,3 +673,48 @@ struct platform_device usb_mass_storage_device = { }, }; #endif +#ifdef CONFIG_USB11_HOST +static struct resource usb11_host_resource[] = { + { + .start = IRQ_USB_HOST, + .end = IRQ_USB_HOST, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK29_USBHOST_PHYS, + .end = RK29_USBHOST_PHYS + RK29_USBHOST_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + +}; + +struct platform_device rk29_device_usb11_host = { + .name = "usb11_host", + .id = -1, + .num_resources = ARRAY_SIZE(usb11_host_resource), + .resource = usb11_host_resource, +}; +#endif +#ifdef CONFIG_USB20_HOST +static struct resource usb20_host_resource[] = { + { + .start = IRQ_USB_OTG1, + .end = IRQ_USB_OTG1, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK29_USBOTG1_PHYS, + .end = RK29_USBOTG1_PHYS + RK29_USBOTG1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + +}; + +struct platform_device rk29_device_usb20_host = { + .name = "usb20_host", + .id = -1, + .num_resources = ARRAY_SIZE(usb20_host_resource), + .resource = usb20_host_resource, +}; +#endif + diff --git a/arch/arm/mach-rk29/devices.h b/arch/arm/mach-rk29/devices.h index 2928b2d1c4fb..b80198fa8325 100755 --- a/arch/arm/mach-rk29/devices.h +++ b/arch/arm/mach-rk29/devices.h @@ -50,10 +50,13 @@ extern struct platform_device rk29_device_adc; extern struct platform_device rk29_device_vmac; extern struct rk29_bl_info rk29_bl_info; extern struct platform_device rk29_device_backlight; -extern struct platform_device rk29_device_dwc_otg; +extern struct platform_device rk29_device_usb20_otg; +extern struct platform_device rk29_device_usb20_host; +extern struct platform_device rk29_device_usb11_host; extern struct platform_device android_usb_device; extern struct usb_mass_storage_platform_data mass_storage_pdata; extern struct platform_device usb_mass_storage_device; extern struct platform_device rk29_device_vmac; extern struct rk29_vmac_platform_data rk29_vmac_pdata; +extern struct platform_device rk29_device_ipp; #endif diff --git a/arch/arm/mach-rk29/include/mach/rk29-ipp.h b/arch/arm/mach-rk29/include/mach/rk29-ipp.h new file mode 100644 index 000000000000..ebbc888d6eee --- /dev/null +++ b/arch/arm/mach-rk29/include/mach/rk29-ipp.h @@ -0,0 +1,103 @@ +#ifndef _RK29_IPP_DRIVER_H_ +#define _RK29_IPP_DRIVER_H_ + +/* Image data */ +struct rk29_ipp_image +{ + uint32_t YrgbMst; // image Y/rgb address + uint32_t CbrMst; // image CbCr address + uint32_t w; // image full width + uint32_t h; // image full height + uint32_t fmt; // color format +}; + +struct rk29_ipp_req { + struct rk29_ipp_image src0; // source0 image + struct rk29_ipp_image dst0; // destination0 image + struct rk29_ipp_image src1; // source1 image + struct rk29_ipp_image dst1; // destination1 image + uint32_t src_vir_w; + uint32_t dst_vir_w; + uint32_t timeout; + uint32_t flag; //rotate +}; + +//uint32_t format ö¾ÙÀàÐÍ +enum +{ + IPP_XRGB_8888 = 0, + IPP_RGB_565 =1 , + IPP_Y_CBCR_H2V1 = 2, //yuv 422sp + IPP_Y_CBCR_H2V2 = 3, //yuv 420sp + IPP_Y_CBCR_H1V1 =6, //yuv 444sp + IPP_IMGTYPE_LIMIT +}; + +typedef enum + { + IPP_ROT_90, + IPP_ROT_180, + IPP_ROT_270, + IPP_ROT_X_FLIP, + IPP_ROT_Y_FLIP, + IPP_ROT_0, + IPP_ROT_LIMIT + } ROT_DEG; + + struct ipp_regs { + uint32_t ipp_config; + uint32_t ipp_src_img_info; + uint32_t ipp_dst_img_info; + uint32_t ipp_img_vir; + uint32_t ipp_int; + uint32_t ipp_src0_y_mst; + uint32_t ipp_src0_Cbr_mst; + uint32_t ipp_src1_y_mst; + uint32_t ipp_src1_Cbr_mst; + uint32_t ipp_dst0_y_mst; + uint32_t ipp_dst0_Cbr_mst; + uint32_t ipp_dst1_y_mst; + uint32_t ipp_dst1_Cbr_mst; + uint32_t ipp_pre_scl_para; + uint32_t ipp_post_scl_para; + uint32_t ipp_swap_ctrl; + uint32_t ipp_pre_img_info; + uint32_t ipp_axi_id; + uint32_t ipp_process_st; +}; + +#define IPP_CONFIG (0x00) +#define IPP_SRC_IMG_INFO (0x04) +#define IPP_DST_IMG_INFO (0x08) +#define IPP_IMG_VIR (0x0c) +#define IPP_INT (0x10) +#define IPP_SRC0_Y_MST (0x14) +#define IPP_SRC0_CBR_MST (0x18) +#define IPP_SRC1_Y_MST (0x1c) +#define IPP_SRC1_CBR_MST (0x20) +#define IPP_DST0_Y_MST (0x24) +#define IPP_DST0_CBR_MST (0x28) +#define IPP_DST1_Y_MST (0x2c) +#define IPP_DST1_CBR_MST (0x30) +#define IPP_PRE_SCL_PARA (0x34) +#define IPP_POST_SCL_PARA (0x38) +#define IPP_SWAP_CTRL (0x3c) +#define IPP_PRE_IMG_INFO (0x40) +#define IPP_AXI_ID (0x44) +#define IPP_SRESET (0x48) +#define IPP_PROCESS_ST (0x50) + +/*ipp config*/ +#define ROT_ENABLE (1<<8) +#define PRE_SCALE (1<<4) +#define POST_SCALE (1<<3) + + +#define IS_YCRCB(img) ((img == IPP_Y_CBCR_H2V1) | (img == IPP_Y_CBCR_H2V2) | \ + (img == IPP_Y_CBCR_H1V1) ) +#define IS_RGB(img) ((img == IPP_RGB_565) | (img == IPP_ARGB_8888) | \ + (img == IPP_XRGB_8888) )) +#define HAS_ALPHA(img) (img == IPP_ARGB_8888) + +int ipp_do_blit(struct rk29_ipp_req *req); +#endif /*_RK29_IPP_DRIVER_H_*/ \ No newline at end of file diff --git a/arch/arm/mach-rk29/include/mach/rk29_camera.h b/arch/arm/mach-rk29/include/mach/rk29_camera.h old mode 100755 new mode 100644 index ae542c97303b..c033e25d8656 --- a/arch/arm/mach-rk29/include/mach/rk29_camera.h +++ b/arch/arm/mach-rk29/include/mach/rk29_camera.h @@ -53,10 +53,16 @@ struct rk29camera_gpio_res { const char *dev_name; }; +struct rk29camera_mem_res { + const char *name; + unsigned int start; + unsigned int size; +}; struct rk29camera_platform_data { int (*io_init)(void); int (*io_deinit)(void); struct rk29camera_gpio_res gpio_res[2]; + struct rk29camera_mem_res meminfo; }; #endif /* __ASM_ARCH_CAMERA_H_ */ diff --git a/arch/arm/mach-rk29/include/mach/rk29_nand.h b/arch/arm/mach-rk29/include/mach/rk29_nand.h index 57f7277a69f5..d41e23153f5d 100644 --- a/arch/arm/mach-rk29/include/mach/rk29_nand.h +++ b/arch/arm/mach-rk29/include/mach/rk29_nand.h @@ -82,26 +82,28 @@ typedef volatile struct tagCHIP_IF }CHIP_IF, *pCHIP_IF; //NANDC Registers -typedef volatile struct tagNANDC +typedef volatile struct tagNANDC { volatile uint32_t FMCTL; volatile uint32_t FMWAIT; volatile uint32_t FLCTL; volatile uint32_t BCHCTL; - volatile uint32_t BCHST; - volatile uint32_t RESERVED1[(0x200-0x14)/4]; //FLR + volatile uint32_t MTRANS_CFG; + volatile uint32_t MTRANS_SADDR0; + volatile uint32_t MTRANS_SADDR1; + volatile uint32_t MTRANS_STAT; + + volatile uint32_t BCHST[8]; + volatile uint32_t FLR1[(0x160-0x40)/4]; + volatile uint32_t NANDC_VER; + volatile uint32_t FLR2[(0x200-0x164)/4]; volatile uint32_t spare[0x200/4]; - volatile uint32_t FMCTL1; - volatile uint32_t FMWAIT1; - volatile uint32_t FLCTL1; - volatile uint32_t BCHCTL1; - volatile uint32_t BCHST1; - volatile uint32_t RESERVED2[(0x200-0x14)/4]; - volatile uint32_t RESERVED3[0x200/4]; + volatile uint32_t RESERVED2[0x400/4]; volatile CHIP_IF chip[8]; volatile uint32_t buf[0x800/4]; }NANDC, *pNANDC; + struct rk29_nand_flash { const struct rk29_nand_timing *timing; /* NAND Flash timing */ const struct rk29_nand_cmdset *cmdset; diff --git a/arch/arm/mach-rk29/vpu_mem.c b/arch/arm/mach-rk29/vpu_mem.c index c88cbadd7471..e9114e0c8cc2 100644 --- a/arch/arm/mach-rk29/vpu_mem.c +++ b/arch/arm/mach-rk29/vpu_mem.c @@ -252,11 +252,11 @@ static int region_check(int index) } /* - * split allocated block from free block + * split new allocated block from free block * the bitmap_sem and region_list_sem must be hold together * the pnode is a ouput region node */ -static int region_split(struct list_head *region_list, struct vpu_mem_region_node *node, int index, int pfn) +static int region_new(struct list_head *region_list, int index, int pfn) { int pfn_free = VPU_MEM_PFN(index); // check pfn is smaller then target index region @@ -274,8 +274,9 @@ static int region_split(struct list_head *region_list, struct vpu_mem_region_nod return -EINVAL; } - if (NULL == node) { + { struct list_head *last; + struct vpu_mem_region_node *node; // check target index region first if (!VPU_MEM_IS_FREE(index)) { #if VPU_MEM_DEBUG @@ -310,12 +311,58 @@ static int region_split(struct list_head *region_list, struct vpu_mem_region_nod region_set_avail(index, VPU_MEM_AVAIL(index) + 1); region_set_ref_count(index, VPU_MEM_REFC(index) + 1); + node->region.index = index; + node->region.ref_count = 1; + } + + return 0; +} + +/* + * link allocated block from free block + * the bitmap_sem and region_list_sem must be hold together + * the pnode is a ouput region node + */ +static int region_link(struct list_head *region_list, int index) +{ + struct vpu_mem_region_node *node = NULL; + struct list_head *list, *tmp; + list_for_each_safe(list, tmp, region_list) { + struct vpu_mem_region_node *p = list_entry(list, struct vpu_mem_region_node, list); + if (index == NODE_REGION_INDEX(p)) { + node = p; + break; + } + } + + if (NULL == node) { + struct list_head *last; + DLOG("link non-exists index %d\n", index); + + // malloc vpu_mem_region_node + node = kmalloc(sizeof(struct vpu_mem_region_node), GFP_KERNEL); + if (NULL == node) { +#if VPU_MEM_DEBUG + printk(KERN_INFO "No space to allocate struct vpu_mem_region_node!"); +#endif + return -ENOMEM; + } + + // search the last node + DLOG("search the last node\n"); + for (last = region_list; !list_is_last(last, region_list);) + last = last->next; + + DLOG("list_add_tail\n"); + list_add_tail(&node->list, last); + node->region.index = index; node->region.ref_count = 1; } else { - region_set_ref_count(index, VPU_MEM_REFC(index) + 1); + DLOG("link existed index %d\n", index); node->region.ref_count++; } + region_set_ref_count(index, VPU_MEM_REFC(index) + 1); return 0; } @@ -391,11 +438,11 @@ static long vpu_mem_allocate(struct file *file, unsigned int len) } } #if VPU_MEM_DEBUG - printk(KERN_INFO "vpu_mem: search curr %d\n!", curr); + //printk(KERN_INFO "vpu_mem: search curr %d\n!", curr); #endif curr = VPU_MEM_NEXT_INDEX(curr); #if VPU_MEM_DEBUG - printk(KERN_INFO "vpu_mem: search next %d\n!", curr); + //printk(KERN_INFO "vpu_mem: search next %d\n!", curr); #endif } @@ -413,7 +460,7 @@ static long vpu_mem_allocate(struct file *file, unsigned int len) down_write(&data->sem); { - int ret = region_split(&data->region_list, NULL, best_fit, pfn); + int ret = region_new(&data->region_list, best_fit, pfn); if (ret) best_fit = -1; } @@ -518,6 +565,7 @@ static int vpu_mem_duplicate(struct file *file, int index) static int vpu_mem_link(struct file *file, int index) { + int err; struct vpu_mem_data *data = (struct vpu_mem_data *)file->private_data; if (!is_vpu_mem_file(file)) { @@ -534,26 +582,21 @@ static int vpu_mem_link(struct file *file, int index) return -EINVAL; } + // check target index region first + if (VPU_MEM_IS_FREE(index)) { +#if VPU_MEM_DEBUG + printk(KERN_INFO "try to link free region %d!", index); +#endif + return -1; + } + /* caller should hold the write lock on vpu_mem_sem! */ - DLOG("link index %d\n", index); - down_write(&data->sem); - { // search exists index - struct list_head *list, *tmp; - list_for_each_safe(list, tmp, &data->region_list) { - struct vpu_mem_region_node *node = list_entry(list, struct vpu_mem_region_node, list); - if (index == NODE_REGION_INDEX(node)) { - region_split(&data->region_list, node, index, VPU_MEM_PFN(index)); - up_write(&data->sem); - return 0; - } - } - // non-exists index - region_split(&data->region_list, NULL, index, VPU_MEM_PFN(index)); - } + err = region_link(&data->region_list, index); up_write(&data->sem); + DLOG("link index %d ret %d\n", index, err); - return 0; + return err; } void vpu_mem_flush(struct file *file, long index) diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c index 70997d5bee2d..dd9598b5e527 100644 --- a/arch/arm/mm/copypage-feroceon.c +++ b/arch/arm/mm/copypage-feroceon.c @@ -18,7 +18,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4-r9, lr} \n\ - mov ip, %0 \n\ + mov ip, %2 \n\ 1: mov lr, r1 \n\ ldmia r1!, {r2 - r9} \n\ pld [lr, #32] \n\ @@ -64,7 +64,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom) mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\ ldmfd sp!, {r4-r9, pc}" : - : "I" (PAGE_SIZE)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE)); } void feroceon_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/copypage-v4wb.c b/arch/arm/mm/copypage-v4wb.c index 9ab098414227..7bc0ac71b371 100644 --- a/arch/arm/mm/copypage-v4wb.c +++ b/arch/arm/mm/copypage-v4wb.c @@ -27,7 +27,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4, lr} @ 2\n\ - mov r2, %0 @ 1\n\ + mov r2, %2 @ 1\n\ ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ stmia r0!, {r3, r4, ip, lr} @ 4\n\ @@ -44,7 +44,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom) mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\ ldmfd sp!, {r4, pc} @ 3" : - : "I" (PAGE_SIZE / 64)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); } void v4wb_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/copypage-v4wt.c b/arch/arm/mm/copypage-v4wt.c index 300efafd6643..35bf60992a14 100644 --- a/arch/arm/mm/copypage-v4wt.c +++ b/arch/arm/mm/copypage-v4wt.c @@ -25,7 +25,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4, lr} @ 2\n\ - mov r2, %0 @ 1\n\ + mov r2, %2 @ 1\n\ ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 1: stmia r0!, {r3, r4, ip, lr} @ 4\n\ ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\ @@ -40,7 +40,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom) mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\ ldmfd sp!, {r4, pc} @ 3" : - : "I" (PAGE_SIZE / 64)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); } void v4wt_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c index bc4525f5ab23..27dc3633d4df 100644 --- a/arch/arm/mm/copypage-xsc3.c +++ b/arch/arm/mm/copypage-xsc3.c @@ -34,7 +34,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom) { asm("\ stmfd sp!, {r4, r5, lr} \n\ - mov lr, %0 \n\ + mov lr, %2 \n\ \n\ pld [r1, #0] \n\ pld [r1, #32] \n\ @@ -67,7 +67,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom) \n\ ldmfd sp!, {r4, r5, pc}" : - : "I" (PAGE_SIZE / 64 - 1)); + : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1)); } void xsc3_mc_copy_user_highpage(struct page *to, struct page *from, diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 10e06801afb3..3191cd659347 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -386,6 +386,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); + if (user_mode(regs)) + goto bad_area; + index = pgd_index(addr); /* diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 9e41985cca25..b388331c25ac 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -272,7 +272,7 @@ __v7_setup: bic r5, r5, #7 << 6 bic r5, r5, #15 orr r5, r5, #3 << 6 @ Tag RAM latency: b011 = 4 cycles - orr r5, r5, #5 @ Data RAM latency: b0101 = 6 cycles + orr r5, r5, #12 @ Data RAM latency: b0101 = 6 cycles mcr p15, 1, r5, c9, c0, 2 #endif diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index cfc4a8b43e6a..c47aa88cc83e 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -223,13 +223,16 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, struct mxc_gpio_port *port = container_of(chip, struct mxc_gpio_port, chip); u32 l; + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); l = __raw_readl(port->base + GPIO_GDIR); if (dir) l |= 1 << offset; else l &= ~(1 << offset); __raw_writel(l, port->base + GPIO_GDIR); + spin_unlock_irqrestore(&port->lock, flags); } static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) @@ -238,9 +241,12 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) container_of(chip, struct mxc_gpio_port, chip); void __iomem *reg = port->base + GPIO_DR; u32 l; + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); __raw_writel(l, reg); + spin_unlock_irqrestore(&port->lock, flags); } static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) @@ -294,6 +300,8 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) port[i].chip.base = i * 32; port[i].chip.ngpio = 32; + spin_lock_init(&port[i].lock); + /* its a serious configuration bug when it fails */ BUG_ON( gpiochip_add(&port[i].chip) < 0 ); diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h index 894d2f87c856..7a0dc5aa2479 100644 --- a/arch/arm/plat-mxc/include/mach/gpio.h +++ b/arch/arm/plat-mxc/include/mach/gpio.h @@ -19,6 +19,7 @@ #ifndef __ASM_ARCH_MXC_GPIO_H__ #define __ASM_ARCH_MXC_GPIO_H__ +#include #include #include @@ -36,6 +37,7 @@ struct mxc_gpio_port { int virtual_irq_start; struct gpio_chip chip; u32 both_edges; + spinlock_t lock; }; int mxc_gpio_init(struct mxc_gpio_port*, int); diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 66dc2d03b7fc..d66cead97d28 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -277,7 +277,7 @@ ENTRY(vfp_put_double) #ifdef CONFIG_VFPv3 @ d16 - d31 registers .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr +1: mcrr p11, 3, r0, r1, c\dr @ fmdrr r0, r1, d\dr mov pc, lr .org 1b + 8 .endr diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h index 8542bc31f63c..93f6c634fdf4 100644 --- a/arch/blackfin/include/asm/cache.h +++ b/arch/blackfin/include/asm/cache.h @@ -15,6 +15,8 @@ #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #define SMP_CACHE_BYTES L1_CACHE_BYTES +#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES + #ifdef CONFIG_SMP #define __cacheline_aligned #else diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h index 2797163b8f4f..7dc0f0f85b7c 100644 --- a/arch/frv/include/asm/cache.h +++ b/arch/frv/include/asm/cache.h @@ -17,6 +17,8 @@ #define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT) #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES + #define __cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) #define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 674a8374c6d9..01ae69be074a 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -677,12 +677,19 @@ sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size) spin_unlock_irqrestore(&ioc->saved_lock, flags); pide = sba_search_bitmap(ioc, dev, pages_needed, 0); - if (unlikely(pide >= (ioc->res_size << 3))) - panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", - ioc->ioc_hpa); + if (unlikely(pide >= (ioc->res_size << 3))) { + printk(KERN_WARNING "%s: I/O MMU @ %p is" + "out of mapping resources, %u %u %lx\n", + __func__, ioc->ioc_hpa, ioc->res_size, + pages_needed, dma_get_seg_boundary(dev)); + return -1; + } #else - panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n", - ioc->ioc_hpa); + printk(KERN_WARNING "%s: I/O MMU @ %p is" + "out of mapping resources, %u %u %lx\n", + __func__, ioc->ioc_hpa, ioc->res_size, + pages_needed, dma_get_seg_boundary(dev)); + return -1; #endif } } @@ -965,6 +972,8 @@ static dma_addr_t sba_map_page(struct device *dev, struct page *page, #endif pide = sba_alloc_range(ioc, dev, size); + if (pide < 0) + return 0; iovp = (dma_addr_t) pide << iovp_shift; @@ -1320,6 +1329,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev, unsigned long dma_offset, dma_len; /* start/len of DMA stream */ int n_mappings = 0; unsigned int max_seg_size = dma_get_max_seg_size(dev); + int idx; while (nents > 0) { unsigned long vaddr = (unsigned long) sba_sg_address(startsg); @@ -1418,16 +1428,22 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev, vcontig_sg->dma_length = vcontig_len; dma_len = (dma_len + dma_offset + ~iovp_mask) & iovp_mask; ASSERT(dma_len <= DMA_CHUNK_SIZE); - dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG - | (sba_alloc_range(ioc, dev, dma_len) << iovp_shift) - | dma_offset); + idx = sba_alloc_range(ioc, dev, dma_len); + if (idx < 0) { + dma_sg->dma_length = 0; + return -1; + } + dma_sg->dma_address = (dma_addr_t)(PIDE_FLAG | (idx << iovp_shift) + | dma_offset); n_mappings++; } return n_mappings; } - +static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs); /** * sba_map_sg - map Scatter/Gather list * @dev: instance of PCI owned by the driver that's asking. @@ -1493,6 +1509,10 @@ static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, ** Access to the virtual address is what forces a two pass algorithm. */ coalesced = sba_coalesce_chunks(ioc, dev, sglist, nents); + if (coalesced < 0) { + sba_unmap_sg_attrs(dev, sglist, nents, dir, attrs); + return 0; + } /* ** Program the I/O Pdir diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 91df9686a0da..8a20b58ba34f 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -94,6 +94,7 @@ ia64_acpi_release_global_lock (unsigned int *lock) #define acpi_noirq 0 /* ACPI always enabled on IA64 */ #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ #define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ +#define acpi_ht 0 /* no HT-only mode on IA64 */ #endif #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ static inline void disable_acpi(void) { } diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h index dfcf75b8426d..c8662cd40fdc 100644 --- a/arch/ia64/include/asm/compat.h +++ b/arch/ia64/include/asm/compat.h @@ -198,7 +198,7 @@ ptr_to_compat(void __user *uptr) } static __inline__ void __user * -compat_alloc_user_space (long len) +arch_compat_alloc_user_space (long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len); diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 3567d54f8cee..331d42bda77a 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -420,22 +420,31 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set ;; RSM_PSR_I(p0, r18, r19) // mask interrupt delivery - mov ar.ccv=0 andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP + mov r8=EINVAL // default to EINVAL #ifdef CONFIG_SMP - mov r17=1 + // __ticket_spin_trylock(r31) + ld4 r17=[r31] ;; - cmpxchg4.acq r18=[r31],r17,ar.ccv // try to acquire the lock - mov r8=EINVAL // default to EINVAL + mov.m ar.ccv=r17 + extr.u r9=r17,17,15 + adds r19=1,r17 + extr.u r18=r17,0,15 ;; + cmp.eq p6,p7=r9,r18 + ;; +(p6) cmpxchg4.acq r9=[r31],r19,ar.ccv +(p6) dep.z r20=r19,1,15 // next serving ticket for unlock +(p7) br.cond.spnt.many .lock_contention + ;; + cmp4.eq p0,p7=r9,r17 + adds r31=2,r31 +(p7) br.cond.spnt.many .lock_contention ld8 r3=[r2] // re-read current->blocked now that we hold the lock - cmp4.ne p6,p0=r18,r0 -(p6) br.cond.spnt.many .lock_contention ;; #else ld8 r3=[r2] // re-read current->blocked now that we hold the lock - mov r8=EINVAL // default to EINVAL #endif add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16 add r19=IA64_TASK_SIGNAL_OFFSET,r16 @@ -490,7 +499,9 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set (p6) br.cond.spnt.few 1b // yes -> retry #ifdef CONFIG_SMP - st4.rel [r31]=r0 // release the lock + // __ticket_spin_unlock(r31) + st2.rel [r31]=r20 + mov r20=0 // i must not leak kernel bits... #endif SSM_PSR_I(p0, p9, r31) ;; @@ -512,7 +523,8 @@ EX(.fail_efault, (p15) st8 [r34]=r3) .sig_pending: #ifdef CONFIG_SMP - st4.rel [r31]=r0 // release the lock + // __ticket_spin_unlock(r31) + st2.rel [r31]=r20 // release the lock #endif SSM_PSR_I(p0, p9, r17) ;; diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index 6c8922856049..4a746ea838ff 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -25,7 +25,7 @@ static int ia64_set_msi_irq_affinity(unsigned int irq, if (irq_prepare_move(irq, cpu)) return -1; - read_msi_msg(irq, &msg); + get_cached_msi_msg(irq, &msg); addr = msg.address_lo; addr &= MSI_ADDR_DEST_ID_MASK; diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 4990495d7531..a35c661e5e89 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -473,7 +473,7 @@ void update_vsyscall_tz(void) { } -void update_vsyscall(struct timespec *wall, struct clocksource *c) +void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult) { unsigned long flags; @@ -481,7 +481,7 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c) /* copy fsyscall clock data */ fsyscall_gtod_data.clk_mask = c->mask; - fsyscall_gtod_data.clk_mult = c->mult; + fsyscall_gtod_data.clk_mult = mult; fsyscall_gtod_data.clk_shift = c->shift; fsyscall_gtod_data.clk_fsys_mmio = c->fsys_mmio; fsyscall_gtod_data.clk_cycle_last = c->cycle_last; diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 0ad09f05efa9..2eb636506496 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1797,7 +1797,8 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm, { struct kvm_memory_slot *memslot; int r, i; - long n, base; + long base; + unsigned long n; unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base + offsetof(struct kvm_vm_data, kvm_mem_dirty_log)); @@ -1810,7 +1811,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm, if (!memslot->dirty_bitmap) goto out; - n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; + n = kvm_dirty_bitmap_bytes(memslot); base = memslot->base_gfn / BITS_PER_LONG; for (i = 0; i < n/sizeof(long); ++i) { @@ -1826,7 +1827,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) { int r; - int n; + unsigned long n; struct kvm_memory_slot *memslot; int is_dirty = 0; @@ -1844,7 +1845,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, if (is_dirty) { kvm_flush_remote_tlbs(kvm); memslot = &kvm->memslots[log->slot]; - n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; + n = kvm_dirty_bitmap_bytes(memslot); memset(memslot->dirty_bitmap, 0, n); } r = 0; diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index ee09d261f2e6..e2cde52116f1 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -120,7 +120,7 @@ static inline void down_spin(struct spinaphore *ss) ia64_invala(); for (;;) { - asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory"); + asm volatile ("ld8.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory"); if (time_before(t, serve)) return; cpu_relax(); diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index fbbfb9701201..9ab2617e46ec 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -174,7 +174,7 @@ static int sn_set_msi_irq_affinity(unsigned int irq, * Release XIO resources for the old MSI PCI address */ - read_msi_msg(irq, &msg); + get_cached_msi_msg(irq, &msg); sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; pdev = sn_pdev->pdi_linux_pcidev; provider = SN_PCIDEV_BUSPROVIDER(pdev); diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h index fed3fd30de7e..ecafbe1718c3 100644 --- a/arch/m68k/include/asm/cache.h +++ b/arch/m68k/include/asm/cache.h @@ -8,4 +8,6 @@ #define L1_CACHE_SHIFT 4 #define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT) +#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES + #endif diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 34187354304a..f76c8581d747 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -69,12 +69,16 @@ export MMU DTB all: linux.bin -BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.% +# With make 3.82 we cannot mix normal and wildcard targets +BOOT_TARGETS1 = linux.bin linux.bin.gz +BOOT_TARGETS2 = simpleImage.% archclean: $(Q)$(MAKE) $(clean)=$(boot) -$(BOOT_TARGETS): vmlinux +$(BOOT_TARGETS1): vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +$(BOOT_TARGETS2): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ define archhelp diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index dd75d673447e..09e7128ec0f0 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -434,7 +434,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %0, %1 # atomic64_add \n" - " addu %0, %2 \n" + " daddu %0, %2 \n" " scd %0, %1 \n" " beqzl %0, 1b \n" " .set mips0 \n" @@ -446,7 +446,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %0, %1 # atomic64_add \n" - " addu %0, %2 \n" + " daddu %0, %2 \n" " scd %0, %1 \n" " beqz %0, 2f \n" " .subsection 2 \n" @@ -479,7 +479,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %0, %1 # atomic64_sub \n" - " subu %0, %2 \n" + " dsubu %0, %2 \n" " scd %0, %1 \n" " beqzl %0, 1b \n" " .set mips0 \n" @@ -491,7 +491,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %0, %1 # atomic64_sub \n" - " subu %0, %2 \n" + " dsubu %0, %2 \n" " scd %0, %1 \n" " beqz %0, 2f \n" " .subsection 2 \n" @@ -524,10 +524,10 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %1, %2 # atomic64_add_return \n" - " addu %0, %1, %3 \n" + " daddu %0, %1, %3 \n" " scd %0, %2 \n" " beqzl %0, 1b \n" - " addu %0, %1, %3 \n" + " daddu %0, %1, %3 \n" " .set mips0 \n" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -538,10 +538,10 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %1, %2 # atomic64_add_return \n" - " addu %0, %1, %3 \n" + " daddu %0, %1, %3 \n" " scd %0, %2 \n" " beqz %0, 2f \n" - " addu %0, %1, %3 \n" + " daddu %0, %1, %3 \n" " .subsection 2 \n" "2: b 1b \n" " .previous \n" @@ -576,10 +576,10 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %1, %2 # atomic64_sub_return \n" - " subu %0, %1, %3 \n" + " dsubu %0, %1, %3 \n" " scd %0, %2 \n" " beqzl %0, 1b \n" - " subu %0, %1, %3 \n" + " dsubu %0, %1, %3 \n" " .set mips0 \n" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -590,10 +590,10 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) __asm__ __volatile__( " .set mips3 \n" "1: lld %1, %2 # atomic64_sub_return \n" - " subu %0, %1, %3 \n" + " dsubu %0, %1, %3 \n" " scd %0, %2 \n" " beqz %0, 2f \n" - " subu %0, %1, %3 \n" + " dsubu %0, %1, %3 \n" " .subsection 2 \n" "2: b 1b \n" " .previous \n" diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index f58aed354bfd..27505bdc386e 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -144,7 +144,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = (struct pt_regs *) ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h index 7950ef4f032c..743385d7b5f2 100644 --- a/arch/mips/include/asm/mach-sibyte/war.h +++ b/arch/mips/include/asm/mach-sibyte/war.h @@ -16,7 +16,11 @@ #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ defined(CONFIG_SB1_PASS_2_WORKAROUNDS) -#define BCM1250_M3_WAR 1 +#ifndef __ASSEMBLY__ +extern int sb1250_m3_workaround_needed(void); +#endif + +#define BCM1250_M3_WAR sb1250_m3_workaround_needed() #define SIBYTE_1956_WAR 1 #else diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index a581d60cbcc2..608dc976455b 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -134,6 +134,12 @@ #define FPU_CSR_COND6 0x40000000 /* $fcc6 */ #define FPU_CSR_COND7 0x80000000 /* $fcc7 */ +/* + * Bits 18 - 20 of the FPU Status Register will be read as 0, + * and should be written as zero. + */ +#define FPU_CSR_RSVD 0x001c0000 + /* * X the exception cause indicator * E the exception enable @@ -161,7 +167,8 @@ #define FPU_CSR_UDF_S 0x00000008 #define FPU_CSR_INE_S 0x00000004 -/* rounding mode */ +/* Bits 0 and 1 of FPU Status Register specify the rounding mode */ +#define FPU_CSR_RM 0x00000003 #define FPU_CSR_RN 0x0 /* nearest */ #define FPU_CSR_RZ 0x1 /* towards zero */ #define FPU_CSR_RU 0x2 /* towards +Infinity */ diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 454b53924490..c15d94b2f3a0 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -75,6 +75,9 @@ struct mips_fpu_emulator_stats fpuemustats; #define FPCREG_RID 0 /* $0 = revision id */ #define FPCREG_CSR 31 /* $31 = csr */ +/* Determine rounding mode from the RM bits of the FCSR */ +#define modeindex(v) ((v) & FPU_CSR_RM) + /* Convert Mips rounding mode (0..3) to IEEE library modes. */ static const unsigned char ieee_rm[4] = { [FPU_CSR_RN] = IEEE754_RN, @@ -381,10 +384,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) (void *) (xcp->cp0_epc), MIPSInst_RT(ir), value); #endif - value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03); - ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03); - /* convert to ieee library modes */ - ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3]; + + /* + * Don't write reserved bits, + * and convert to ieee library modes + */ + ctx->fcr31 = (value & + ~(FPU_CSR_RSVD | FPU_CSR_RM)) | + ieee_rm[modeindex(value)]; } if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) { return SIGFPE; diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index bb1719a55d22..266c0036323a 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -73,9 +73,6 @@ static int __cpuinit m4kc_tlbp_war(void) enum label_id { label_second_part = 1, label_leave, -#ifdef MODULE_START - label_module_alloc, -#endif label_vmalloc, label_vmalloc_done, label_tlbw_hazard, @@ -92,9 +89,6 @@ enum label_id { UASM_L_LA(_second_part) UASM_L_LA(_leave) -#ifdef MODULE_START -UASM_L_LA(_module_alloc) -#endif UASM_L_LA(_vmalloc) UASM_L_LA(_vmalloc_done) UASM_L_LA(_tlbw_hazard) @@ -731,10 +725,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) * create the plain linear handler */ if (bcm1250_m3_war()) { - UASM_i_MFC0(&p, K0, C0_BADVADDR); - UASM_i_MFC0(&p, K1, C0_ENTRYHI); + unsigned int segbits = 44; + + uasm_i_dmfc0(&p, K0, C0_BADVADDR); + uasm_i_dmfc0(&p, K1, C0_ENTRYHI); uasm_i_xor(&p, K0, K0, K1); - UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1); + uasm_i_dsrl32(&p, K1, K0, 62 - 32); + uasm_i_dsrl(&p, K0, K0, 12 + 1); + uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32); + uasm_i_or(&p, K0, K0, K1); uasm_il_bnez(&p, &r, K0, label_leave); /* No need for uasm_i_nop */ } @@ -802,8 +801,6 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) } else { #if defined(CONFIG_HUGETLB_PAGE) const enum label_id ls = label_tlb_huge_update; -#elif defined(MODULE_START) - const enum label_id ls = label_module_alloc; #else const enum label_id ls = label_vmalloc; #endif @@ -1250,10 +1247,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void) memset(relocs, 0, sizeof(relocs)); if (bcm1250_m3_war()) { - UASM_i_MFC0(&p, K0, C0_BADVADDR); - UASM_i_MFC0(&p, K1, C0_ENTRYHI); + unsigned int segbits = 44; + + uasm_i_dmfc0(&p, K0, C0_BADVADDR); + uasm_i_dmfc0(&p, K1, C0_ENTRYHI); uasm_i_xor(&p, K0, K0, K1); - UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1); + uasm_i_dsrl32(&p, K1, K0, 62 - 32); + uasm_i_dsrl(&p, K0, K0, 12 + 1); + uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32); + uasm_i_or(&p, K0, K0, K1); uasm_il_bnez(&p, &r, K0, label_leave); /* No need for uasm_i_nop */ } diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index f467199676a8..e1bd527377ed 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -62,7 +62,7 @@ enum opcode { insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, - insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, + insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori }; @@ -116,6 +116,7 @@ static struct insn insn_table[] __cpuinitdata = { { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, + { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, @@ -362,6 +363,7 @@ I_u2s3u1(_lw) I_u1u2u3(_mfc0) I_u1u2u3(_mtc0) I_u2u1u3(_ori) +I_u3u1u2(_or) I_u2s3u1(_pref) I_0(_rfe) I_u2s3u1(_sc) diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h index c6d1e3dd82d4..5198ae5f64ee 100644 --- a/arch/mips/mm/uasm.h +++ b/arch/mips/mm/uasm.h @@ -78,6 +78,7 @@ Ip_u2s3u1(_lw); Ip_u1u2u3(_mfc0); Ip_u1u2u3(_mtc0); Ip_u2u1u3(_ori); +Ip_u3u1u2(_or); Ip_u2s3u1(_pref); Ip_0(_rfe); Ip_u2s3u1(_sc); diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c index 2fbfa1a8c3a9..bf80921f2f56 100644 --- a/arch/mips/mti-malta/malta-pci.c +++ b/arch/mips/mti-malta/malta-pci.c @@ -247,6 +247,8 @@ void __init mips_pcibios_init(void) iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ ioport_resource.end = controller->io_resource->end; + controller->io_map_base = mips_io_port_base; + register_pci_controller(controller); } diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c index eee4f3dfc410..98e86ddb86cc 100644 --- a/arch/mips/nxp/pnx8550/common/pci.c +++ b/arch/mips/nxp/pnx8550/common/pci.c @@ -44,6 +44,7 @@ extern struct pci_ops pnx8550_pci_ops; static struct pci_controller pnx8550_controller = { .pci_ops = &pnx8550_pci_ops, + .io_map_base = PNX8550_PORT_BASE, .io_resource = &pci_io_resource, .mem_resource = &pci_mem_resource, }; diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c index 2aed50fef10f..64246c9c875c 100644 --- a/arch/mips/nxp/pnx8550/common/setup.c +++ b/arch/mips/nxp/pnx8550/common/setup.c @@ -113,7 +113,7 @@ void __init plat_mem_setup(void) PNX8550_GLB2_ENAB_INTA_O = 0; /* IO/MEM resources. */ - set_io_port_base(KSEG1); + set_io_port_base(PNX8550_PORT_BASE); ioport_resource.start = 0; ioport_resource.end = ~0; iomem_resource.start = 0; diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index 32548b5d68d6..421e1a0d1e29 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -944,6 +944,7 @@ static struct pci_controller msp_pci_controller = { .pci_ops = &msp_pci_ops, .mem_resource = &pci_mem_resource, .mem_offset = 0, + .io_map_base = MSP_PCI_IOSPACE_BASE, .io_resource = &pci_io_resource, .io_offset = 0 }; diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c index 0357946f30e6..cf5e1a25cb7d 100644 --- a/arch/mips/pci/pci-yosemite.c +++ b/arch/mips/pci/pci-yosemite.c @@ -54,6 +54,7 @@ static int __init pmc_yosemite_setup(void) panic(ioremap_failed); set_io_port_base(io_v_base); + py_controller.io_map_base = io_v_base; TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1); ioport_resource.end = TITAN_IO_SIZE - 1; diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index 0444da1e23c2..92da3155ce07 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c @@ -87,6 +87,21 @@ static int __init setup_bcm1250(void) return ret; } +int sb1250_m3_workaround_needed(void) +{ + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: + case K_SYS_SOC_TYPE_BCM1250_ALT2: + case K_SYS_SOC_TYPE_BCM1125: + case K_SYS_SOC_TYPE_BCM1125H: + return soc_pass < K_SYS_REVISION_BCM1250_C0; + + default: + return 0; + } +} + static int __init setup_bcm112x(void) { int ret = 0; diff --git a/arch/mn10300/include/asm/cache.h b/arch/mn10300/include/asm/cache.h index e03cfa2e997e..6e2fe28dde4e 100644 --- a/arch/mn10300/include/asm/cache.h +++ b/arch/mn10300/include/asm/cache.h @@ -21,6 +21,8 @@ #define L1_CACHE_DISPARITY L1_CACHE_NENTRIES * L1_CACHE_BYTES #endif +#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES + /* data cache purge registers * - read from the register to unconditionally purge that cache line * - write address & 0xffffff00 to conditionally purge that cache line diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 7f32611a7a5e..7c77fa93ab33 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -146,7 +146,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static __inline__ void __user *compat_alloc_user_space(long len) +static __inline__ void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = ¤t->thread.regs; return (void __user *)regs->gr[30]; diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 4c247e02d9b1..df971fa0c32f 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -1123,7 +1123,6 @@ static char __attribute__((aligned(64))) iodc_dbuf[4096]; */ int pdc_iodc_print(const unsigned char *str, unsigned count) { - static int posx; /* for simple TAB-Simulation... */ unsigned int i; unsigned long flags; @@ -1133,19 +1132,12 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) iodc_dbuf[i+0] = '\r'; iodc_dbuf[i+1] = '\n'; i += 2; - posx = 0; goto print; - case '\t': - while (posx & 7) { - iodc_dbuf[i] = ' '; - i++, posx++; - } - break; case '\b': /* BS */ - posx -= 2; + i--; /* overwrite last */ default: iodc_dbuf[i] = str[i]; - i++, posx++; + i++; break; } } diff --git a/arch/parisc/math-emu/decode_exc.c b/arch/parisc/math-emu/decode_exc.c index 3ca1c6149218..27a7492ddb0d 100644 --- a/arch/parisc/math-emu/decode_exc.c +++ b/arch/parisc/math-emu/decode_exc.c @@ -342,6 +342,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[]) return SIGNALCODE(SIGFPE, FPE_FLTINV); case DIVISIONBYZEROEXCEPTION: update_trap_counts(Fpu_register, aflags, bflags, trap_counts); + Clear_excp_register(exception_index); return SIGNALCODE(SIGFPE, FPE_FLTDIV); case INEXACTEXCEPTION: update_trap_counts(Fpu_register, aflags, bflags, trap_counts); diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 1a54a3b3a3fa..c107b7474890 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -158,9 +158,11 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ # Default to zImage, override when needed all: zImage -BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.% +# With make 3.82 we cannot mix normal and wildcard targets +BOOT_TARGETS1 := zImage zImage.initrd uImage +BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% -PHONY += $(BOOT_TARGETS) +PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) boot := arch/$(ARCH)/boot @@ -175,10 +177,16 @@ relocs_check: arch/powerpc/relocs_check.pl vmlinux zImage: relocs_check endif -$(BOOT_TARGETS): vmlinux +$(BOOT_TARGETS1): vmlinux + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) +$(BOOT_TARGETS2): vmlinux $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) -bootwrapper_install %.dtb: + +bootwrapper_install: + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) + +%.dtb: $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) define archhelp diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 4774c2f92232..8d0fff39cdba 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h @@ -133,7 +133,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = current->thread.regs; unsigned long usp = regs->gpr[1]; diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index abbc2aaaced5..c1de3c9a1d65 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -135,43 +135,5 @@ static inline int irqs_disabled_flags(unsigned long flags) */ struct irq_chip; -#ifdef CONFIG_PERF_EVENTS - -#ifdef CONFIG_PPC64 -static inline unsigned long test_perf_event_pending(void) -{ - unsigned long x; - - asm volatile("lbz %0,%1(13)" - : "=r" (x) - : "i" (offsetof(struct paca_struct, perf_event_pending))); - return x; -} - -static inline void set_perf_event_pending(void) -{ - asm volatile("stb %0,%1(13)" : : - "r" (1), - "i" (offsetof(struct paca_struct, perf_event_pending))); -} - -static inline void clear_perf_event_pending(void) -{ - asm volatile("stb %0,%1(13)" : : - "r" (0), - "i" (offsetof(struct paca_struct, perf_event_pending))); -} -#endif /* CONFIG_PPC64 */ - -#else /* CONFIG_PERF_EVENTS */ - -static inline unsigned long test_perf_event_pending(void) -{ - return 0; -} - -static inline void clear_perf_event_pending(void) {} -#endif /* CONFIG_PERF_EVENTS */ - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HW_IRQ_H */ diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index 2828f9d0f66d..fa6648aaf070 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h @@ -137,6 +137,11 @@ struct device_node * find_device_pe(struct device_node *dn); void eeh_sysfs_add_device(struct pci_dev *pdev); void eeh_sysfs_remove_device(struct pci_dev *pdev); +static inline const char *eeh_pci_name(struct pci_dev *pdev) +{ + return pdev ? pci_name(pdev) : ""; +} + #endif /* CONFIG_EEH */ #else /* CONFIG_PCI */ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0812b0f414bb..692c056566c7 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -133,7 +133,6 @@ int main(void) DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr)); DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); - DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending)); DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); #ifdef CONFIG_PPC_MM_SLICES DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct, diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 9763267e38b4..917cebc2f262 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) 2: TRACE_AND_RESTORE_IRQ(r5); -#ifdef CONFIG_PERF_EVENTS - /* check paca->perf_event_pending if we're enabling ints */ - lbz r3,PACAPERFPEND(r13) - and. r3,r3,r5 - beq 27f - bl .perf_event_do_pending -27: -#endif /* CONFIG_PERF_EVENTS */ - /* extract EE bit and use it to restore paca->hard_enabled */ ld r3,_MSR(r1) rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index c38afdb45d7b..0a3cf9eb4ca4 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -563,15 +563,21 @@ __secondary_start: /* Set thread priority to MEDIUM */ HMT_MEDIUM - /* Do early setup for that CPU (stab, slb, hash table pointer) */ - bl .early_setup_secondary - /* Initialize the kernel stack. Just a repeat for iSeries. */ LOAD_REG_ADDR(r3, current_set) sldi r28,r24,3 /* get current_set[cpu#] */ - ldx r1,r3,r28 - addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD - std r1,PACAKSAVE(r13) + ldx r14,r3,r28 + addi r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD + std r14,PACAKSAVE(r13) + + /* Do early setup for that CPU (stab, slb, hash table pointer) */ + bl .early_setup_secondary + + /* + * setup the new stack pointer, but *don't* use this until + * translation is on. + */ + mr r1, r14 /* Clear backchain so we get nice backtraces */ li r7,0 diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index e5d121177984..8564a412e7a6 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include @@ -138,11 +137,6 @@ notrace void raw_local_irq_restore(unsigned long en) } #endif /* CONFIG_PPC_STD_MMU_64 */ - if (test_perf_event_pending()) { - clear_perf_event_pending(); - perf_event_do_pending(); - } - /* * if (get_paca()->hard_enabled) return; * But again we need to take care that gcc gets hard_enabled directly diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index 479574413a93..ec9b95f635bb 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c @@ -173,9 +173,11 @@ static int p970_marked_instr_event(u64 event) switch (unit) { case PM_VPU: mask = 0x4c; /* byte 0 bits 2,3,6 */ + break; case PM_LSU0: /* byte 2 bits 0,2,3,4,6; all of byte 1 */ mask = 0x085dff00; + break; case PM_LSU1L: mask = 0x50 << 24; /* byte 3 bits 4,6 */ break; diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index a136a11c490d..7143d4ce1cd8 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -530,25 +530,60 @@ void __init iSeries_time_init_early(void) } #endif /* CONFIG_PPC_ISERIES */ -#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32) -DEFINE_PER_CPU(u8, perf_event_pending); +#ifdef CONFIG_PERF_EVENTS -void set_perf_event_pending(void) +/* + * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable... + */ +#ifdef CONFIG_PPC64 +static inline unsigned long test_perf_event_pending(void) { - get_cpu_var(perf_event_pending) = 1; - set_dec(1); - put_cpu_var(perf_event_pending); + unsigned long x; + + asm volatile("lbz %0,%1(13)" + : "=r" (x) + : "i" (offsetof(struct paca_struct, perf_event_pending))); + return x; } +static inline void set_perf_event_pending_flag(void) +{ + asm volatile("stb %0,%1(13)" : : + "r" (1), + "i" (offsetof(struct paca_struct, perf_event_pending))); +} + +static inline void clear_perf_event_pending(void) +{ + asm volatile("stb %0,%1(13)" : : + "r" (0), + "i" (offsetof(struct paca_struct, perf_event_pending))); +} + +#else /* 32-bit */ + +DEFINE_PER_CPU(u8, perf_event_pending); + +#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1 #define test_perf_event_pending() __get_cpu_var(perf_event_pending) #define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0 -#else /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */ +#endif /* 32 vs 64 bit */ + +void set_perf_event_pending(void) +{ + preempt_disable(); + set_perf_event_pending_flag(); + set_dec(1); + preempt_enable(); +} + +#else /* CONFIG_PERF_EVENTS */ #define test_perf_event_pending() 0 #define clear_perf_event_pending() -#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */ +#endif /* CONFIG_PERF_EVENTS */ /* * For iSeries shared processors, we have to let the hypervisor @@ -576,10 +611,6 @@ void timer_interrupt(struct pt_regs * regs) set_dec(DECREMENTER_MAX); #ifdef CONFIG_PPC32 - if (test_perf_event_pending()) { - clear_perf_event_pending(); - perf_event_do_pending(); - } if (atomic_read(&ppc_n_lost_interrupts) != 0) do_IRQ(regs); #endif @@ -597,6 +628,11 @@ void timer_interrupt(struct pt_regs * regs) calculate_steal_time(); + if (test_perf_event_pending()) { + clear_perf_event_pending(); + perf_event_do_pending(); + } + #ifdef CONFIG_PPC_ISERIES if (firmware_has_feature(FW_FEATURE_ISERIES)) get_lppaca()->int_dword.fields.decr_int = 0; @@ -828,7 +864,8 @@ static cycle_t timebase_read(struct clocksource *cs) return (cycle_t)get_tb(); } -void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) +void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, + u32 mult) { u64 t2x, stamp_xsec; @@ -841,7 +878,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) /* XXX this assumes clock->shift == 22 */ /* 4611686018 ~= 2^(20+64-22) / 1e9 */ - t2x = (u64) clock->mult * 4611686018ULL; + t2x = (u64) mult * 4611686018ULL; stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC; do_div(stamp_xsec, 1000000000); stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2a4551f78f60..ff184f4771e9 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -176,7 +176,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) { struct kvm_vcpu *vcpu; vcpu = kvmppc_core_vcpu_create(kvm, id); - kvmppc_create_vcpu_debugfs(vcpu, id); + if (!IS_ERR(vcpu)) + kvmppc_create_vcpu_debugfs(vcpu, id); return vcpu; } diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S index 64e2e499e32a..3ac0cd3a5373 100644 --- a/arch/powerpc/lib/string.S +++ b/arch/powerpc/lib/string.S @@ -71,7 +71,7 @@ _GLOBAL(strcmp) _GLOBAL(strncmp) PPC_LCMPI r5,0 - beqlr + ble- 2f mtctr r5 addi r5,r3,-1 addi r4,r4,-1 @@ -82,6 +82,8 @@ _GLOBAL(strncmp) beqlr 1 bdnzt eq,1b blr +2: li r3,0 + blr _GLOBAL(strlen) addi r4,r3,-1 diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index dc93e95b256e..45f4e61b2632 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -131,15 +131,10 @@ void settlbcam(int index, unsigned long virt, phys_addr_t phys, TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR; TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0); -#ifndef CONFIG_KGDB /* want user access for breakpoints */ if (flags & _PAGE_USER) { TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); } -#else - TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; - TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); -#endif tlbcam_addrs[index].start = virt; tlbcam_addrs[index].limit = virt + size - 1; diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index ae06c6236d9c..c8fc4dc8f572 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -1077,7 +1077,7 @@ static int calculate_lfsr(int n) index = ENTRIES-1; /* make sure index is valid */ - if ((index > ENTRIES) || (index < 0)) + if ((index >= ENTRIES) || (index < 0)) index = ENTRIES-1; return initial_lfsr[index]; diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index ccd8dd03b8c9..3304f32fc7b8 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -491,7 +491,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) pdn->eeh_mode & EEH_MODE_NOCHECK) { ignored_check++; pr_debug("EEH: Ignored check (%x) for %s %s\n", - pdn->eeh_mode, pci_name (dev), dn->full_name); + pdn->eeh_mode, eeh_pci_name(dev), dn->full_name); return 0; } @@ -515,7 +515,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) printk (KERN_ERR "EEH: %d reads ignored for recovering device at " "location=%s driver=%s pci addr=%s\n", pdn->eeh_check_count, location, - dev->driver->name, pci_name(dev)); + dev->driver->name, eeh_pci_name(dev)); printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n", dev->driver->name); dump_stack(); diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 0e8db6771252..52c4b4038cd7 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -353,7 +353,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) location = location ? location : "unknown"; printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " "for location=%s pci addr=%s\n", - location, pci_name(event->dev)); + location, eeh_pci_name(event->dev)); return NULL; } @@ -384,7 +384,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) pci_str = pci_name (frozen_pdn->pcidev); drv_str = pcid_name (frozen_pdn->pcidev); } else { - pci_str = pci_name (event->dev); + pci_str = eeh_pci_name(event->dev); drv_str = pcid_name (event->dev); } diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index ddb80f5d850b..ec5df8f519c7 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c @@ -80,7 +80,7 @@ static int eeh_event_handler(void * dummy) eeh_mark_slot(event->dn, EEH_MODE_RECOVERING); printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", - pci_name(event->dev)); + eeh_pci_name(event->dev)); pdn = handle_eeh_events(event); diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index ebff6d9a4e39..c2c172042db2 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -66,30 +66,6 @@ static void pseries_mach_cpu_die(void) for(;;); } -static int qcss_tok; /* query-cpu-stopped-state token */ - -/* Get state of physical CPU. - * Return codes: - * 0 - The processor is in the RTAS stopped state - * 1 - stop-self is in progress - * 2 - The processor is not in the RTAS stopped state - * -1 - Hardware Error - * -2 - Hardware Busy, Try again later. - */ -static int query_cpu_stopped(unsigned int pcpu) -{ - int cpu_status, status; - - status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); - if (status != 0) { - printk(KERN_ERR - "RTAS query-cpu-stopped-state failed: %i\n", status); - return status; - } - - return cpu_status; -} - static int pseries_cpu_disable(void) { int cpu = smp_processor_id(); @@ -113,8 +89,9 @@ static void pseries_cpu_die(unsigned int cpu) unsigned int pcpu = get_hard_smp_processor_id(cpu); for (tries = 0; tries < 25; tries++) { - cpu_status = query_cpu_stopped(pcpu); - if (cpu_status == 0 || cpu_status == -1) + cpu_status = smp_query_cpu_stopped(pcpu); + if (cpu_status == QCSS_STOPPED || + cpu_status == QCSS_HARDWARE_ERROR) break; cpu_relax(); } @@ -256,6 +233,7 @@ static int __init pseries_cpu_hotplug_init(void) { struct device_node *np; const char *typep; + int qcss_tok; for_each_node_by_name(np, "interrupt-controller") { typep = of_get_property(np, "compatible", NULL); diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index a24a6b2333b2..45f634c02208 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -4,6 +4,14 @@ #include #include +/* Get state of physical CPU from query_cpu_stopped */ +int smp_query_cpu_stopped(unsigned int pcpu); +#define QCSS_STOPPED 0 +#define QCSS_STOPPING 1 +#define QCSS_NOT_STOPPED 2 +#define QCSS_HARDWARE_ERROR -1 +#define QCSS_HARDWARE_BUSY -2 + static inline long poll_pending(void) { return plpar_hcall_norets(H_POLL_PENDING); diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 440000cc7130..3afa079d178b 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -56,6 +56,28 @@ */ static cpumask_t of_spin_map; +/* Query where a cpu is now. Return codes #defined in plpar_wrappers.h */ +int smp_query_cpu_stopped(unsigned int pcpu) +{ + int cpu_status, status; + int qcss_tok = rtas_token("query-cpu-stopped-state"); + + if (qcss_tok == RTAS_UNKNOWN_SERVICE) { + printk(KERN_INFO "Firmware doesn't support " + "query-cpu-stopped-state\n"); + return QCSS_HARDWARE_ERROR; + } + + status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); + if (status != 0) { + printk(KERN_ERR + "RTAS query-cpu-stopped-state failed: %i\n", status); + return status; + } + + return cpu_status; +} + /** * smp_startup_cpu() - start the given cpu * @@ -81,6 +103,12 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) pcpu = get_hard_smp_processor_id(lcpu); + /* Check to see if the CPU out of FW already for kexec */ + if (smp_query_cpu_stopped(pcpu) == QCSS_NOT_STOPPED){ + cpu_set(lcpu, of_spin_map); + return 1; + } + /* Fixup atomic count: it exited inside IRQ handler. */ task_thread_info(paca[lcpu].__current)->preempt_count = 0; diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 01a08020bc0e..0c940d38d6b7 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -180,7 +180,7 @@ static inline int is_compat_task(void) #endif -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { unsigned long stack; diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index f23961ada7fb..258ba88b7b50 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h @@ -183,6 +183,7 @@ struct s390_idle_data { unsigned long long idle_count; unsigned long long idle_enter; unsigned long long idle_time; + int nohz_delay; }; DECLARE_PER_CPU(struct s390_idle_data, s390_idle); @@ -198,4 +199,11 @@ static inline void s390_idle_check(void) vtime_start_cpu(); } +static inline int s390_nohz_delay(int cpu) +{ + return per_cpu(s390_idle, cpu).nohz_delay != 0; +} + +#define arch_needs_cpu(cpu) s390_nohz_delay(cpu) + #endif /* _S390_CPUTIME_H */ diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 015e27da40eb..24fd61132e35 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -95,7 +95,6 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck); static int notrace s390_revalidate_registers(struct mci *mci) { int kill_task; - u64 tmpclock; u64 zero; void *fpt_save_area, *fpt_creg_save_area; @@ -214,11 +213,10 @@ static int notrace s390_revalidate_registers(struct mci *mci) : "0", "cc"); #endif /* Revalidate clock comparator register */ - asm volatile( - " stck 0(%1)\n" - " sckc 0(%1)" - : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory"); - + if (S390_lowcore.clock_comparator == -1) + set_clock_comparator(get_clock()); + else + set_clock_comparator(S390_lowcore.clock_comparator); /* Check if old PSW is valid */ if (!mci->wp) /* diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 653c6a178740..08f883842e21 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -632,7 +632,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { - long ret; + long ret = 0; /* Do the secure computing check first. */ secure_computing(regs->gprs[2]); @@ -641,7 +641,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) * The sysc_tracesys code in entry.S stored the system * call number to gprs[2]. */ - ret = regs->gprs[2]; if (test_thread_flag(TIF_SYSCALL_TRACE) && (tracehook_report_syscall_entry(regs) || regs->gprs[2] >= NR_syscalls)) { @@ -663,7 +662,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) regs->gprs[2], regs->orig_gpr2, regs->gprs[3], regs->gprs[4], regs->gprs[5]); - return ret; + return ret ?: regs->gprs[2]; } asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c index 0de305b598ce..59618bcd99b7 100644 --- a/arch/s390/kernel/s390_ext.c +++ b/arch/s390/kernel/s390_ext.c @@ -126,6 +126,8 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code) /* Serve timer interrupts first. */ clock_comparator_work(); kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; + if (code != 0x1004) + __get_cpu_var(s390_idle).nohz_delay = 1; index = ext_hash(code); for (p = ext_int_hash[index]; p; p = p->next) { if (likely(p->code == code)) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 34162a0b2caa..68e1ecf5ebab 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -214,7 +214,8 @@ struct clocksource * __init clocksource_default_clock(void) return &clocksource_tod; } -void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) +void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, + u32 mult) { if (clock != &clocksource_tod) return; diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index c41bb0d416e1..b59a812a010e 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -167,6 +167,8 @@ void vtime_stop_cpu(void) /* Wait for external, I/O or machine check interrupt. */ psw.mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT; + idle->nohz_delay = 0; + /* Check if the CPU timer needs to be reprogrammed. */ if (vq->do_spt) { __u64 vmax = VTIMER_MAX_SLICE; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ca2d31277b3b..75fbf199d71e 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -338,11 +338,13 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, rc = kvm_vcpu_init(vcpu, kvm, id); if (rc) - goto out_free_cpu; + goto out_free_sie_block; VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu, vcpu->arch.sie_block); return vcpu; +out_free_sie_block: + free_page((unsigned long)(vcpu->arch.sie_block)); out_free_cpu: kfree(vcpu); out_nomem: diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 752b362bf651..7c37ec359ec2 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -29,17 +29,21 @@ static void __udelay_disabled(unsigned long long usecs) { unsigned long mask, cr0, cr0_saved; u64 clock_saved; + u64 end; + mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; + end = get_clock() + (usecs << 12); clock_saved = local_tick_disable(); - set_clock_comparator(get_clock() + (usecs << 12)); __ctl_store(cr0_saved, 0, 0); cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; __ctl_load(cr0 , 0, 0); - mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; lockdep_off(); - trace_hardirqs_on(); - __load_psw_mask(mask); - local_irq_disable(); + do { + set_clock_comparator(end); + trace_hardirqs_on(); + __load_psw_mask(mask); + local_irq_disable(); + } while (get_clock() < end); lockdep_on(); __ctl_load(cr0_saved, 0, 0); local_tick_enable(clock_saved); diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index fd56a71ca9d9..974ba71df4a8 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -132,7 +132,7 @@ void decompress_kernel(void) output_addr = (CONFIG_MEMORY_START + 0x2000); #else output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE); -#ifdef CONFIG_29BIT +#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED) output_addr |= P2SEG; #endif #endif diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h index ccb1d93bb043..bf6939cc4744 100644 --- a/arch/sh/include/asm/elf.h +++ b/arch/sh/include/asm/elf.h @@ -212,7 +212,9 @@ extern void __kernel_vsyscall; #define VSYSCALL_AUX_ENT \ if (vdso_enabled) \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ + else \ + NEW_AUX_ENT(AT_IGNORE, 0); #else #define VSYSCALL_AUX_ENT #endif /* CONFIG_VSYSCALL */ @@ -220,7 +222,7 @@ extern void __kernel_vsyscall; #ifdef CONFIG_SH_FPU #define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT) #else -#define FPU_AUX_ENT +#define FPU_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0) #endif extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 160db1003cfb..71a9c3c47e6f 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -69,6 +69,7 @@ asmlinkage void __cpuinit start_secondary(void) unsigned int cpu; struct mm_struct *mm = &init_mm; + enable_mmu(); atomic_inc(&mm->mm_count); atomic_inc(&mm->mm_users); current->active_mm = mm; diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index f2e48009989e..f5cc06f44c17 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -20,14 +20,14 @@ #define atomic64_set(v, i) (((v)->counter) = i) extern void atomic_add(int, atomic_t *); -extern void atomic64_add(int, atomic64_t *); +extern void atomic64_add(long, atomic64_t *); extern void atomic_sub(int, atomic_t *); -extern void atomic64_sub(int, atomic64_t *); +extern void atomic64_sub(long, atomic64_t *); extern int atomic_add_ret(int, atomic_t *); -extern int atomic64_add_ret(int, atomic64_t *); +extern long atomic64_add_ret(long, atomic64_t *); extern int atomic_sub_ret(int, atomic_t *); -extern int atomic64_sub_ret(int, atomic64_t *); +extern long atomic64_sub_ret(long, atomic64_t *); #define atomic_dec_return(v) atomic_sub_ret(1, v) #define atomic64_dec_return(v) atomic64_sub_ret(1, v) @@ -91,7 +91,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -static inline int atomic64_add_unless(atomic64_t *v, long a, long u) +static inline long atomic64_add_unless(atomic64_t *v, long a, long u) { long c, old; c = atomic64_read(v); diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index 0e706257918f..612bb3862c6d 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h @@ -166,7 +166,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h index 93fe21e02c86..2889574608db 100644 --- a/arch/sparc/include/asm/io_32.h +++ b/arch/sparc/include/asm/io_32.h @@ -8,7 +8,7 @@ #include /* IO address mapping routines need this */ #include -#define page_to_phys(page) (((page) - mem_map) << PAGE_SHIFT) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) static inline u32 flip_dword (u32 l) { @@ -249,10 +249,14 @@ extern void iounmap(volatile void __iomem *addr); #define ioread8(X) readb(X) #define ioread16(X) readw(X) +#define ioread16be(X) __raw_readw(X) #define ioread32(X) readl(X) +#define ioread32be(X) __raw_readl(X) #define iowrite8(val,X) writeb(val,X) #define iowrite16(val,X) writew(val,X) +#define iowrite16be(val,X) __raw_writew(val,X) #define iowrite32(val,X) writel(val,X) +#define iowrite32be(val,X) __raw_writel(val,X) static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count) { diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index 4aee21dc9c6f..9517d063c79c 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h @@ -468,10 +468,14 @@ static inline void iounmap(volatile void __iomem *addr) #define ioread8(X) readb(X) #define ioread16(X) readw(X) +#define ioread16be(X) __raw_readw(X) #define ioread32(X) readl(X) +#define ioread32be(X) __raw_readl(X) #define iowrite8(val,X) writeb(val,X) #define iowrite16(val,X) writew(val,X) +#define iowrite16be(val,X) __raw_writew(val,X) #define iowrite32(val,X) writel(val,X) +#define iowrite32be(val,X) __raw_writel(val,X) /* Create a virtual mapping cookie for an IO port range */ extern void __iomem *ioport_map(unsigned long port, unsigned int nr); diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index a5db0317b5fb..3e0b2d62303d 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code, char *buf, int buflen); /* Retain physical memory to the caller across soft resets. */ -extern unsigned long prom_retain(const char *name, - unsigned long pa_low, unsigned long pa_high, - long size, long align); +extern int prom_retain(const char *name, unsigned long size, + unsigned long align, unsigned long *paddr); /* Load explicit I/D TLB entries into the calling processor. */ extern long prom_itlb_load(unsigned long index, @@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void); extern int prom_ihandle2path(int handle, char *buffer, int bufsize); /* Client interface level routines. */ -extern long p1275_cmd(const char *, long, ...); - -#if 0 -#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x)) -#else -#define P1275_SIZE(x) x -#endif - -/* We support at most 16 input and 1 output argument */ -#define P1275_ARG_NUMBER 0 -#define P1275_ARG_IN_STRING 1 -#define P1275_ARG_OUT_BUF 2 -#define P1275_ARG_OUT_32B 3 -#define P1275_ARG_IN_FUNCTION 4 -#define P1275_ARG_IN_BUF 5 -#define P1275_ARG_IN_64B 6 - -#define P1275_IN(x) ((x) & 0xf) -#define P1275_OUT(x) (((x) << 4) & 0xf0) -#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o)) -#define P1275_ARG(n,x) ((x) << ((n)*3 + 8)) +extern void p1275_cmd_direct(unsigned long *); #endif /* !(__SPARC64_OPLIB_H) */ diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index f72080bdda94..156707b0f18d 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h @@ -143,7 +143,7 @@ extern unsigned long pfn_base; #define phys_to_virt __va #define ARCH_PFN_OFFSET (pfn_base) -#define virt_to_page(kaddr) (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT))) +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) #define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr)) #define virt_addr_valid(kaddr) ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr) diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index ff9ead640c4a..43cf002d480b 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -228,6 +228,10 @@ static const struct of_device_id ecpp_match[] = { .name = "parallel", .compatible = "ns87317-ecpp", }, + { + .name = "parallel", + .compatible = "pnpALI,1533,3", + }, {}, }; diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h index a303c9d64d84..e4c61a18bb28 100644 --- a/arch/sparc/include/asm/rwsem-const.h +++ b/arch/sparc/include/asm/rwsem-const.h @@ -5,7 +5,7 @@ #define RWSEM_UNLOCKED_VALUE 0x00000000 #define RWSEM_ACTIVE_BIAS 0x00000001 #define RWSEM_ACTIVE_MASK 0x0000ffff -#define RWSEM_WAITING_BIAS 0xffff0000 +#define RWSEM_WAITING_BIAS (-0x00010000) #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) diff --git a/arch/sparc/include/asm/stat.h b/arch/sparc/include/asm/stat.h index 55db5eca08e2..a232e9e1f4e5 100644 --- a/arch/sparc/include/asm/stat.h +++ b/arch/sparc/include/asm/stat.h @@ -53,8 +53,8 @@ struct stat { ino_t st_ino; mode_t st_mode; short st_nlink; - uid_t st_uid; - gid_t st_gid; + unsigned short st_uid; + unsigned short st_gid; unsigned short st_rdev; off_t st_size; time_t st_atime; diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index f3b5466c389c..4589ca33220f 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -99,7 +99,7 @@ static int __devinit clock_board_probe(struct of_device *op, p->leds_resource.start = (unsigned long) (p->clock_regs + CLOCK_CTRL); - p->leds_resource.end = p->leds_resource.end; + p->leds_resource.end = p->leds_resource.start; p->leds_resource.name = "leds"; p->leds_pdev.name = "sunfire-clockboard-leds"; @@ -194,7 +194,7 @@ static int __devinit fhc_probe(struct of_device *op, if (!p->central) { p->leds_resource.start = (unsigned long) (p->pregs + FHC_PREGS_CTRL); - p->leds_resource.end = p->leds_resource.end; + p->leds_resource.end = p->leds_resource.start; p->leds_resource.name = "leds"; p->leds_pdev.name = "sunfire-fhc-leds"; diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 2830b415e214..c49865b30719 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -526,7 +526,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, * Set some valid stack frames to give to the child. */ childstack = (struct sparc_stackf __user *) - (sp & ~0x7UL); + (sp & ~0xfUL); parentstack = (struct sparc_stackf __user *) regs->u_regs[UREG_FP]; diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index c3f1cce0e95e..cb70476bd8f5 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -398,11 +398,11 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) } else __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); - /* Now 8-byte align the stack as this is mandatory in the - * Sparc ABI due to how register windows work. This hides - * the restriction from thread libraries etc. -DaveM + /* Now align the stack as this is mandatory in the Sparc ABI + * due to how register windows work. This hides the + * restriction from thread libraries etc. */ - csp &= ~7UL; + csp &= ~15UL; distance = fp - psp; rval = (csp - distance); diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index ba5b09ad6666..75fad425e249 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -120,8 +120,8 @@ struct rt_signal_frame32 { }; /* Align macros */ -#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 7) & (~7))) -#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7))) +#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 15) & (~15))) +#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 15) & (~15))) int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) { @@ -420,15 +420,17 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns sp = current->sas_ss_sp + current->sas_ss_size; } + sp -= framesize; + /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack * alignment. Second, if we took this signal because the stack * is not aligned properly, we'd like to take the signal cleanly * and report that. */ - sp &= ~7UL; + sp &= ~15UL; - return (void __user *)(sp - framesize); + return (void __user *) sp; } static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) @@ -451,8 +453,66 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) return err; } -static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, - int signo, sigset_t *oldset) +/* The I-cache flush instruction only works in the primary ASI, which + * right now is the nucleus, aka. kernel space. + * + * Therefore we have to kick the instructions out using the kernel + * side linear mapping of the physical address backing the user + * instructions. + */ +static void flush_signal_insns(unsigned long address) +{ + unsigned long pstate, paddr; + pte_t *ptep, pte; + pgd_t *pgdp; + pud_t *pudp; + pmd_t *pmdp; + + /* Commit all stores of the instructions we are about to flush. */ + wmb(); + + /* Disable cross-call reception. In this way even a very wide + * munmap() on another cpu can't tear down the page table + * hierarchy from underneath us, since that can't complete + * until the IPI tlb flush returns. + */ + + __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); + __asm__ __volatile__("wrpr %0, %1, %%pstate" + : : "r" (pstate), "i" (PSTATE_IE)); + + pgdp = pgd_offset(current->mm, address); + if (pgd_none(*pgdp)) + goto out_irqs_on; + pudp = pud_offset(pgdp, address); + if (pud_none(*pudp)) + goto out_irqs_on; + pmdp = pmd_offset(pudp, address); + if (pmd_none(*pmdp)) + goto out_irqs_on; + + ptep = pte_offset_map(pmdp, address); + pte = *ptep; + if (!pte_present(pte)) + goto out_unmap; + + paddr = (unsigned long) page_address(pte_page(pte)); + + __asm__ __volatile__("flush %0 + %1" + : /* no outputs */ + : "r" (paddr), + "r" (address & (PAGE_SIZE - 1)) + : "memory"); + +out_unmap: + pte_unmap(ptep); +out_irqs_on: + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); + +} + +static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, + int signo, sigset_t *oldset) { struct signal_frame32 __user *sf; int sigframe_size; @@ -545,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) { regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; } else { - /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); - pgd_t *pgdp = pgd_offset(current->mm, address); - pud_t *pudp = pud_offset(pgdp, address); - pmd_t *pmdp = pmd_offset(pudp, address); - pte_t *ptep; - pte_t pte; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); @@ -560,34 +614,22 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; - preempt_disable(); - ptep = pte_offset_map(pmdp, address); - pte = *ptep; - if (pte_present(pte)) { - unsigned long page = (unsigned long) - page_address(pte_page(pte)); - - wmb(); - __asm__ __volatile__("flush %0 + %1" - : /* no outputs */ - : "r" (page), - "r" (address & (PAGE_SIZE - 1)) - : "memory"); - } - pte_unmap(ptep); - preempt_enable(); + flush_signal_insns(address); } - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, - unsigned long signr, sigset_t *oldset, - siginfo_t *info) +static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, + unsigned long signr, sigset_t *oldset, + siginfo_t *info) { struct rt_signal_frame32 __user *sf; int sigframe_size; @@ -685,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (ka->ka_restorer) regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; else { - /* Flush instruction space. */ unsigned long address = ((unsigned long)&(sf->insns[0])); - pgd_t *pgdp = pgd_offset(current->mm, address); - pud_t *pudp = pud_offset(pgdp, address); - pmd_t *pmdp = pmd_offset(pudp, address); - pte_t *ptep; regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); @@ -702,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, if (err) goto sigsegv; - preempt_disable(); - ptep = pte_offset_map(pmdp, address); - if (pte_present(*ptep)) { - unsigned long page = (unsigned long) - page_address(pte_page(*ptep)); - - wmb(); - __asm__ __volatile__("flush %0 + %1" - : /* no outputs */ - : "r" (page), - "r" (address & (PAGE_SIZE - 1)) - : "memory"); - } - pte_unmap(ptep); - preempt_enable(); + flush_signal_insns(address); } - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signr, current); + return -EFAULT; } -static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, - siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs) +static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, + siginfo_t *info, + sigset_t *oldset, struct pt_regs *regs) { + int err; + if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame32(ka, regs, signr, oldset, info); + err = setup_rt_frame32(ka, regs, signr, oldset, info); else - setup_frame32(ka, regs, signr, oldset); + err = setup_frame32(ka, regs, signr, oldset); + + if (err) + return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); @@ -741,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, sigaddset(¤t->blocked,signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_signal_handler(signr, info, ka, regs, 0); + + return 0; } static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, @@ -787,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, if (signr > 0) { if (restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); - handle_signal32(signr, &ka, &info, oldset, regs); - - /* A signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - - tracehook_signal_handler(signr, &info, &ka, regs, 0); + if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { + /* A signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TS_RESTORE_SIGMASK flag. + */ + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + } return; } if (restart_syscall && @@ -807,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 7ce1a1005b1d..5e5c5fd03783 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -267,15 +267,17 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re sp = current->sas_ss_sp + current->sas_ss_size; } + sp -= framesize; + /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack * alignment. Second, if we took this signal because the stack * is not aligned properly, we'd like to take the signal cleanly * and report that. */ - sp &= ~7UL; + sp &= ~15UL; - return (void __user *)(sp - framesize); + return (void __user *) sp; } static inline int @@ -313,8 +315,8 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) return err; } -static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, - int signo, sigset_t *oldset) +static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, + int signo, sigset_t *oldset) { struct signal_frame __user *sf; int sigframe_size, err; @@ -382,16 +384,19 @@ static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } - return; + return 0; sigill_and_return: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, - int signo, sigset_t *oldset, siginfo_t *info) +static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, + int signo, sigset_t *oldset, siginfo_t *info) { struct rt_signal_frame __user *sf; int sigframe_size; @@ -464,22 +469,30 @@ static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* Flush instruction space. */ flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); } - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static inline void +static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { + int err; + if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(ka, regs, signr, oldset, info); + err = setup_rt_frame(ka, regs, signr, oldset, info); else - setup_frame(ka, regs, signr, oldset); + err = setup_frame(ka, regs, signr, oldset); + + if (err) + return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); @@ -487,6 +500,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_signal_handler(signr, info, ka, regs, 0); + + return 0; } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -544,17 +561,15 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); - handle_signal(signr, &ka, &info, oldset, regs); - - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - - tracehook_signal_handler(signr, &info, &ka, regs, 0); + if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { + /* a signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TIF_RESTORE_SIGMASK flag. + */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + } return; } if (restart_syscall && @@ -565,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) regs->u_regs[UREG_I0] = orig_i0; regs->pc -= 4; regs->npc -= 4; + pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->pc -= 4; regs->npc -= 4; + pt_regs_clear_syscall(regs); } /* if there's no signal to deliver, we just put the saved sigmask diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 647afbda7ae1..006fe4515886 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -353,7 +353,7 @@ void do_rt_sigreturn(struct pt_regs *regs) /* Checks if the fp is valid */ static int invalid_frame_pointer(void __user *fp, int fplen) { - if (((unsigned long) fp) & 7) + if (((unsigned long) fp) & 15) return 1; return 0; } @@ -396,18 +396,20 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * sp = current->sas_ss_sp + current->sas_ss_size; } + sp -= framesize; + /* Always align the stack frame. This handles two cases. First, * sigaltstack need not be mindful of platform specific stack * alignment. Second, if we took this signal because the stack * is not aligned properly, we'd like to take the signal cleanly * and report that. */ - sp &= ~7UL; + sp &= ~15UL; - return (void __user *)(sp - framesize); + return (void __user *) sp; } -static inline void +static inline int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, int signo, sigset_t *oldset, siginfo_t *info) { @@ -481,26 +483,37 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, } /* 4. return to kernel instructions */ regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; - return; + return 0; sigill: do_exit(SIGILL); + return -EINVAL; + sigsegv: force_sigsegv(signo, current); + return -EFAULT; } -static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, - siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs) +static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, + siginfo_t *info, + sigset_t *oldset, struct pt_regs *regs) { - setup_rt_frame(ka, regs, signr, oldset, - (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); + int err; + + err = setup_rt_frame(ka, regs, signr, oldset, + (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); + if (err) + return err; spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NOMASK)) sigaddset(¤t->blocked,signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_signal_handler(signr, info, ka, regs, 0); + + return 0; } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -569,16 +582,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); - handle_signal(signr, &ka, &info, oldset, regs); - - /* A signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - - tracehook_signal_handler(signr, &info, &ka, regs, 0); + if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { + /* A signal was successfully delivered; the saved + * sigmask will have been stored in the signal frame, + * and will be restored by sigreturn, so we can simply + * clear the TS_RESTORE_SIGMASK flag. + */ + current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + } return; } if (restart_syscall && @@ -589,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } if (restart_syscall && regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { regs->u_regs[UREG_G1] = __NR_restart_syscall; regs->tpc -= 4; regs->tnpc -= 4; + pt_regs_clear_syscall(regs); } /* If there's no signal to deliver, we just put the saved sigmask diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index 8c91d9b29a2f..db15d123f054 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S @@ -191,10 +191,12 @@ tsb_dtlb_load: tsb_itlb_load: /* Executable bit must be set. */ -661: andcc %g5, _PAGE_EXEC_4U, %g0 - .section .sun4v_1insn_patch, "ax" +661: sethi %hi(_PAGE_EXEC_4U), %g4 + andcc %g5, %g4, %g0 + .section .sun4v_2insn_patch, "ax" .word 661b andcc %g5, _PAGE_EXEC_4V, %g0 + nop .previous be,pn %xcc, tsb_do_fault diff --git a/arch/sparc/prom/cif.S b/arch/sparc/prom/cif.S index 5f27ad779c0c..9c86b4b7d429 100644 --- a/arch/sparc/prom/cif.S +++ b/arch/sparc/prom/cif.S @@ -9,18 +9,18 @@ #include .text - .globl prom_cif_interface -prom_cif_interface: - sethi %hi(p1275buf), %o0 - or %o0, %lo(p1275buf), %o0 - ldx [%o0 + 0x010], %o1 ! prom_cif_stack - save %o1, -192, %sp - ldx [%i0 + 0x008], %l2 ! prom_cif_handler + .globl prom_cif_direct +prom_cif_direct: + sethi %hi(p1275buf), %o1 + or %o1, %lo(p1275buf), %o1 + ldx [%o1 + 0x0010], %o2 ! prom_cif_stack + save %o2, -192, %sp + ldx [%i1 + 0x0008], %l2 ! prom_cif_handler mov %g4, %l0 mov %g5, %l1 mov %g6, %l3 call %l2 - add %i0, 0x018, %o0 ! prom_args + mov %i0, %o0 ! prom_args mov %l0, %g4 mov %l1, %g5 mov %l3, %g6 diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index e1c3fc87484d..7b707b6a3fca 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout; inline int prom_nbgetchar(void) { + unsigned long args[7]; char inc; - if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)| - P1275_INOUT(3,1), - prom_stdin, &inc, P1275_SIZE(1)) == 1) + args[0] = (unsigned long) "read"; + args[1] = 3; + args[2] = 1; + args[3] = (unsigned int) prom_stdin; + args[4] = (unsigned long) &inc; + args[5] = 1; + args[6] = (unsigned long) -1; + + p1275_cmd_direct(args); + + if (args[6] == 1) return inc; - else - return -1; + return -1; } /* Non blocking put character to console device, returns -1 if @@ -37,12 +45,22 @@ prom_nbgetchar(void) inline int prom_nbputchar(char c) { + unsigned long args[7]; char outc; outc = c; - if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| - P1275_INOUT(3,1), - prom_stdout, &outc, P1275_SIZE(1)) == 1) + + args[0] = (unsigned long) "write"; + args[1] = 3; + args[2] = 1; + args[3] = (unsigned int) prom_stdout; + args[4] = (unsigned long) &outc; + args[5] = 1; + args[6] = (unsigned long) -1; + + p1275_cmd_direct(args); + + if (args[6] == 1) return 0; else return -1; @@ -68,7 +86,15 @@ prom_putchar(char c) void prom_puts(const char *s, int len) { - p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| - P1275_INOUT(3,1), - prom_stdout, s, P1275_SIZE(len)); + unsigned long args[7]; + + args[0] = (unsigned long) "write"; + args[1] = 3; + args[2] = 1; + args[3] = (unsigned int) prom_stdout; + args[4] = (unsigned long) s; + args[5] = len; + args[6] = (unsigned long) -1; + + p1275_cmd_direct(args); } diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c index 9dbd803e46e1..a017119e7ef1 100644 --- a/arch/sparc/prom/devops_64.c +++ b/arch/sparc/prom/devops_64.c @@ -18,16 +18,32 @@ int prom_devopen(const char *dstr) { - return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| - P1275_INOUT(1,1), - dstr); + unsigned long args[5]; + + args[0] = (unsigned long) "open"; + args[1] = 1; + args[2] = 1; + args[3] = (unsigned long) dstr; + args[4] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[4]; } /* Close the device described by device handle 'dhandle'. */ int prom_devclose(int dhandle) { - p1275_cmd ("close", P1275_INOUT(1,0), dhandle); + unsigned long args[4]; + + args[0] = (unsigned long) "close"; + args[1] = 1; + args[2] = 0; + args[3] = (unsigned int) dhandle; + + p1275_cmd_direct(args); + return 0; } @@ -37,5 +53,15 @@ prom_devclose(int dhandle) void prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) { - p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo); + unsigned long args[7]; + + args[0] = (unsigned long) "seek"; + args[1] = 3; + args[2] = 1; + args[3] = (unsigned int) dhandle; + args[4] = seekhi; + args[5] = seeklo; + args[6] = (unsigned long) -1; + + p1275_cmd_direct(args); } diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index 39fc6af21b7c..6cb1581d6aef 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c @@ -20,10 +20,17 @@ int prom_service_exists(const char *service_name) { - int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_INOUT(1, 1), service_name); + unsigned long args[5]; - if (err) + args[0] = (unsigned long) "test"; + args[1] = 1; + args[2] = 1; + args[3] = (unsigned long) service_name; + args[4] = (unsigned long) -1; + + p1275_cmd_direct(args); + + if (args[4]) return 0; return 1; } @@ -31,30 +38,47 @@ int prom_service_exists(const char *service_name) void prom_sun4v_guest_soft_state(void) { const char *svc = "SUNW,soft-state-supported"; + unsigned long args[3]; if (!prom_service_exists(svc)) return; - p1275_cmd(svc, P1275_INOUT(0, 0)); + args[0] = (unsigned long) svc; + args[1] = 0; + args[2] = 0; + p1275_cmd_direct(args); } /* Reset and reboot the machine with the command 'bcommand'. */ void prom_reboot(const char *bcommand) { + unsigned long args[4]; + #ifdef CONFIG_SUN_LDOMS if (ldom_domaining_enabled) ldom_reboot(bcommand); #endif - p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_INOUT(1, 0), bcommand); + args[0] = (unsigned long) "boot"; + args[1] = 1; + args[2] = 0; + args[3] = (unsigned long) bcommand; + + p1275_cmd_direct(args); } /* Forth evaluate the expression contained in 'fstring'. */ void prom_feval(const char *fstring) { + unsigned long args[5]; + if (!fstring || fstring[0] == 0) return; - p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_INOUT(1, 1), fstring); + args[0] = (unsigned long) "interpret"; + args[1] = 1; + args[2] = 1; + args[3] = (unsigned long) fstring; + args[4] = (unsigned long) -1; + + p1275_cmd_direct(args); } EXPORT_SYMBOL(prom_feval); @@ -68,6 +92,7 @@ extern void smp_release(void); */ void prom_cmdline(void) { + unsigned long args[3]; unsigned long flags; local_irq_save(flags); @@ -76,7 +101,11 @@ void prom_cmdline(void) smp_capture(); #endif - p1275_cmd("enter", P1275_INOUT(0, 0)); + args[0] = (unsigned long) "enter"; + args[1] = 0; + args[2] = 0; + + p1275_cmd_direct(args); #ifdef CONFIG_SMP smp_release(); @@ -90,22 +119,32 @@ void prom_cmdline(void) */ void notrace prom_halt(void) { + unsigned long args[3]; + #ifdef CONFIG_SUN_LDOMS if (ldom_domaining_enabled) ldom_power_off(); #endif again: - p1275_cmd("exit", P1275_INOUT(0, 0)); + args[0] = (unsigned long) "exit"; + args[1] = 0; + args[2] = 0; + p1275_cmd_direct(args); goto again; /* PROM is out to get me -DaveM */ } void prom_halt_power_off(void) { + unsigned long args[3]; + #ifdef CONFIG_SUN_LDOMS if (ldom_domaining_enabled) ldom_power_off(); #endif - p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); + args[0] = (unsigned long) "SUNW,power-off"; + args[1] = 0; + args[2] = 0; + p1275_cmd_direct(args); /* if nothing else helps, we just halt */ prom_halt(); @@ -114,10 +153,15 @@ void prom_halt_power_off(void) /* Set prom sync handler to call function 'funcp'. */ void prom_setcallback(callback_func_t funcp) { + unsigned long args[5]; if (!funcp) return; - p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) | - P1275_INOUT(1, 1), funcp); + args[0] = (unsigned long) "set-callback"; + args[1] = 1; + args[2] = 1; + args[3] = (unsigned long) funcp; + args[4] = (unsigned long) -1; + p1275_cmd_direct(args); } /* Get the idprom and stuff it into buffer 'idbuf'. Returns the @@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void) } /* Load explicit I/D TLB entries. */ +static long tlb_load(const char *type, unsigned long index, + unsigned long tte_data, unsigned long vaddr) +{ + unsigned long args[9]; + + args[0] = (unsigned long) prom_callmethod_name; + args[1] = 5; + args[2] = 1; + args[3] = (unsigned long) type; + args[4] = (unsigned int) prom_get_mmu_ihandle(); + args[5] = vaddr; + args[6] = tte_data; + args[7] = index; + args[8] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (long) args[8]; +} + long prom_itlb_load(unsigned long index, unsigned long tte_data, unsigned long vaddr) { - return p1275_cmd(prom_callmethod_name, - (P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_ARG(2, P1275_ARG_IN_64B) | - P1275_ARG(3, P1275_ARG_IN_64B) | - P1275_INOUT(5, 1)), - "SUNW,itlb-load", - prom_get_mmu_ihandle(), - /* And then our actual args are pushed backwards. */ - vaddr, - tte_data, - index); + return tlb_load("SUNW,itlb-load", index, tte_data, vaddr); } long prom_dtlb_load(unsigned long index, unsigned long tte_data, unsigned long vaddr) { - return p1275_cmd(prom_callmethod_name, - (P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_ARG(2, P1275_ARG_IN_64B) | - P1275_ARG(3, P1275_ARG_IN_64B) | - P1275_INOUT(5, 1)), - "SUNW,dtlb-load", - prom_get_mmu_ihandle(), - /* And then our actual args are pushed backwards. */ - vaddr, - tte_data, - index); + return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr); } int prom_map(int mode, unsigned long size, unsigned long vaddr, unsigned long paddr) { - int ret = p1275_cmd(prom_callmethod_name, - (P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_ARG(3, P1275_ARG_IN_64B) | - P1275_ARG(4, P1275_ARG_IN_64B) | - P1275_ARG(6, P1275_ARG_IN_64B) | - P1275_INOUT(7, 1)), - prom_map_name, - prom_get_mmu_ihandle(), - mode, - size, - vaddr, - 0, - paddr); + unsigned long args[11]; + int ret; + args[0] = (unsigned long) prom_callmethod_name; + args[1] = 7; + args[2] = 1; + args[3] = (unsigned long) prom_map_name; + args[4] = (unsigned int) prom_get_mmu_ihandle(); + args[5] = (unsigned int) mode; + args[6] = size; + args[7] = vaddr; + args[8] = 0; + args[9] = paddr; + args[10] = (unsigned long) -1; + + p1275_cmd_direct(args); + + ret = (int) args[10]; if (ret == 0) ret = -1; return ret; @@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long size, void prom_unmap(unsigned long size, unsigned long vaddr) { - p1275_cmd(prom_callmethod_name, - (P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_ARG(2, P1275_ARG_IN_64B) | - P1275_ARG(3, P1275_ARG_IN_64B) | - P1275_INOUT(4, 0)), - prom_unmap_name, - prom_get_mmu_ihandle(), - size, - vaddr); + unsigned long args[7]; + + args[0] = (unsigned long) prom_callmethod_name; + args[1] = 4; + args[2] = 0; + args[3] = (unsigned long) prom_unmap_name; + args[4] = (unsigned int) prom_get_mmu_ihandle(); + args[5] = size; + args[6] = vaddr; + + p1275_cmd_direct(args); } /* Set aside physical memory which is not touched or modified * across soft resets. */ -unsigned long prom_retain(const char *name, - unsigned long pa_low, unsigned long pa_high, - long size, long align) +int prom_retain(const char *name, unsigned long size, + unsigned long align, unsigned long *paddr) { - /* XXX I don't think we return multiple values correctly. - * XXX OBP supposedly returns pa_low/pa_high here, how does - * XXX it work? - */ + unsigned long args[11]; - /* If align is zero, the pa_low/pa_high args are passed, - * else they are not. + args[0] = (unsigned long) prom_callmethod_name; + args[1] = 5; + args[2] = 3; + args[3] = (unsigned long) "SUNW,retain"; + args[4] = (unsigned int) prom_get_memory_ihandle(); + args[5] = align; + args[6] = size; + args[7] = (unsigned long) name; + args[8] = (unsigned long) -1; + args[9] = (unsigned long) -1; + args[10] = (unsigned long) -1; + + p1275_cmd_direct(args); + + if (args[8]) + return (int) args[8]; + + /* Next we get "phys_high" then "phys_low". On 64-bit + * the phys_high cell is don't care since the phys_low + * cell has the full value. */ - if (align == 0) - return p1275_cmd("SUNW,retain", - (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)), - name, pa_low, pa_high, size, align); - else - return p1275_cmd("SUNW,retain", - (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)), - name, size, align); + *paddr = args[10]; + + return 0; } /* Get "Unumber" string for the SIMM at the given @@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code, unsigned long phys_addr, char *buf, int buflen) { - return p1275_cmd(prom_callmethod_name, - (P1275_ARG(0, P1275_ARG_IN_STRING) | - P1275_ARG(3, P1275_ARG_OUT_BUF) | - P1275_ARG(6, P1275_ARG_IN_64B) | - P1275_INOUT(8, 2)), - "SUNW,get-unumber", prom_get_memory_ihandle(), - buflen, buf, P1275_SIZE(buflen), - 0, phys_addr, syndrome_code); + unsigned long args[12]; + + args[0] = (unsigned long) prom_callmethod_name; + args[1] = 7; + args[2] = 2; + args[3] = (unsigned long) "SUNW,get-unumber"; + args[4] = (unsigned int) prom_get_memory_ihandle(); + args[5] = buflen; + args[6] = (unsigned long) buf; + args[7] = 0; + args[8] = phys_addr; + args[9] = (unsigned int) syndrome_code; + args[10] = (unsigned long) -1; + args[11] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[10]; } /* Power management extensions. */ void prom_sleepself(void) { - p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0)); + unsigned long args[3]; + + args[0] = (unsigned long) "SUNW,sleep-self"; + args[1] = 0; + args[2] = 0; + p1275_cmd_direct(args); } int prom_sleepsystem(void) { - return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1)); + unsigned long args[4]; + + args[0] = (unsigned long) "SUNW,sleep-system"; + args[1] = 0; + args[2] = 1; + args[3] = (unsigned long) -1; + p1275_cmd_direct(args); + + return (int) args[3]; } int prom_wakeupsystem(void) { - return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1)); + unsigned long args[4]; + + args[0] = (unsigned long) "SUNW,wakeup-system"; + args[1] = 0; + args[2] = 1; + args[3] = (unsigned long) -1; + p1275_cmd_direct(args); + + return (int) args[3]; } #ifdef CONFIG_SMP void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) { - p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg); + unsigned long args[6]; + + args[0] = (unsigned long) "SUNW,start-cpu"; + args[1] = 3; + args[2] = 0; + args[3] = (unsigned int) cpunode; + args[4] = pc; + args[5] = arg; + p1275_cmd_direct(args); } void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) { - p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0), - cpuid, pc, arg); + unsigned long args[6]; + + args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid"; + args[1] = 3; + args[2] = 0; + args[3] = (unsigned int) cpuid; + args[4] = pc; + args[5] = arg; + p1275_cmd_direct(args); } void prom_stopcpu_cpuid(int cpuid) { - p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0), - cpuid); + unsigned long args[4]; + + args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid"; + args[1] = 1; + args[2] = 0; + args[3] = (unsigned int) cpuid; + p1275_cmd_direct(args); } void prom_stopself(void) { - p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0)); + unsigned long args[3]; + + args[0] = (unsigned long) "SUNW,stop-self"; + args[1] = 0; + args[2] = 0; + p1275_cmd_direct(args); } void prom_idleself(void) { - p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0)); + unsigned long args[3]; + + args[0] = (unsigned long) "SUNW,idle-self"; + args[1] = 0; + args[2] = 0; + p1275_cmd_direct(args); } void prom_resumecpu(int cpunode) { - p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode); + unsigned long args[4]; + + args[0] = (unsigned long) "SUNW,resume-cpu"; + args[1] = 1; + args[2] = 0; + args[3] = (unsigned int) cpunode; + p1275_cmd_direct(args); } #endif diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c index 4b7c937bba61..7ae5b5408d7c 100644 --- a/arch/sparc/prom/p1275.c +++ b/arch/sparc/prom/p1275.c @@ -22,126 +22,32 @@ struct { long prom_callback; /* 0x00 */ void (*prom_cif_handler)(long *); /* 0x08 */ unsigned long prom_cif_stack; /* 0x10 */ - unsigned long prom_args [23]; /* 0x18 */ - char prom_buffer [3000]; } p1275buf; extern void prom_world(int); -extern void prom_cif_interface(void); +extern void prom_cif_direct(unsigned long *args); extern void prom_cif_callback(void); /* - * This provides SMP safety on the p1275buf. prom_callback() drops this lock - * to allow recursuve acquisition. + * This provides SMP safety on the p1275buf. */ DEFINE_SPINLOCK(prom_entry_lock); -long p1275_cmd(const char *service, long fmt, ...) +void p1275_cmd_direct(unsigned long *args) { - char *p, *q; unsigned long flags; - int nargs, nrets, i; - va_list list; - long attrs, x; - - p = p1275buf.prom_buffer; - spin_lock_irqsave(&prom_entry_lock, flags); - - p1275buf.prom_args[0] = (unsigned long)p; /* service */ - strcpy (p, service); - p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); - p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */ - p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */ - attrs = fmt >> 8; - va_start(list, fmt); - for (i = 0; i < nargs; i++, attrs >>= 3) { - switch (attrs & 0x7) { - case P1275_ARG_NUMBER: - p1275buf.prom_args[i + 3] = - (unsigned)va_arg(list, long); - break; - case P1275_ARG_IN_64B: - p1275buf.prom_args[i + 3] = - va_arg(list, unsigned long); - break; - case P1275_ARG_IN_STRING: - strcpy (p, va_arg(list, char *)); - p1275buf.prom_args[i + 3] = (unsigned long)p; - p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); - break; - case P1275_ARG_OUT_BUF: - (void) va_arg(list, char *); - p1275buf.prom_args[i + 3] = (unsigned long)p; - x = va_arg(list, long); - i++; attrs >>= 3; - p = (char *)(((long)(p + (int)x + 7)) & ~7); - p1275buf.prom_args[i + 3] = x; - break; - case P1275_ARG_IN_BUF: - q = va_arg(list, char *); - p1275buf.prom_args[i + 3] = (unsigned long)p; - x = va_arg(list, long); - i++; attrs >>= 3; - memcpy (p, q, (int)x); - p = (char *)(((long)(p + (int)x + 7)) & ~7); - p1275buf.prom_args[i + 3] = x; - break; - case P1275_ARG_OUT_32B: - (void) va_arg(list, char *); - p1275buf.prom_args[i + 3] = (unsigned long)p; - p += 32; - break; - case P1275_ARG_IN_FUNCTION: - p1275buf.prom_args[i + 3] = - (unsigned long)prom_cif_callback; - p1275buf.prom_callback = va_arg(list, long); - break; - } - } - va_end(list); + raw_local_save_flags(flags); + raw_local_irq_restore(PIL_NMI); + spin_lock(&prom_entry_lock); prom_world(1); - prom_cif_interface(); + prom_cif_direct(args); prom_world(0); - attrs = fmt >> 8; - va_start(list, fmt); - for (i = 0; i < nargs; i++, attrs >>= 3) { - switch (attrs & 0x7) { - case P1275_ARG_NUMBER: - (void) va_arg(list, long); - break; - case P1275_ARG_IN_STRING: - (void) va_arg(list, char *); - break; - case P1275_ARG_IN_FUNCTION: - (void) va_arg(list, long); - break; - case P1275_ARG_IN_BUF: - (void) va_arg(list, char *); - (void) va_arg(list, long); - i++; attrs >>= 3; - break; - case P1275_ARG_OUT_BUF: - p = va_arg(list, char *); - x = va_arg(list, long); - memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x); - i++; attrs >>= 3; - break; - case P1275_ARG_OUT_32B: - p = va_arg(list, char *); - memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32); - break; - } - } - va_end(list); - x = p1275buf.prom_args [nargs + 3]; - - spin_unlock_irqrestore(&prom_entry_lock, flags); - - return x; + spin_unlock(&prom_entry_lock); + raw_local_irq_restore(flags); } void prom_cif_init(void *cif_handler, void *cif_stack) diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 8ea73ddc61dc..6a05c76f58fd 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c @@ -16,22 +16,39 @@ #include #include +static int prom_node_to_node(const char *type, int node) +{ + unsigned long args[5]; + + args[0] = (unsigned long) type; + args[1] = 1; + args[2] = 1; + args[3] = (unsigned int) node; + args[4] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[4]; +} + /* Return the child of node 'node' or zero if no this node has no * direct descendent. */ inline int __prom_getchild(int node) { - return p1275_cmd ("child", P1275_INOUT(1, 1), node); + return prom_node_to_node("child", node); } inline int prom_getchild(int node) { int cnode; - if(node == -1) return 0; + if (node == -1) + return 0; cnode = __prom_getchild(node); - if(cnode == -1) return 0; - return (int)cnode; + if (cnode == -1) + return 0; + return cnode; } EXPORT_SYMBOL(prom_getchild); @@ -39,10 +56,12 @@ inline int prom_getparent(int node) { int cnode; - if(node == -1) return 0; - cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node); - if(cnode == -1) return 0; - return (int)cnode; + if (node == -1) + return 0; + cnode = prom_node_to_node("parent", node); + if (cnode == -1) + return 0; + return cnode; } /* Return the next sibling of node 'node' or zero if no more siblings @@ -50,7 +69,7 @@ inline int prom_getparent(int node) */ inline int __prom_getsibling(int node) { - return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node); + return prom_node_to_node(prom_peer_name, node); } inline int prom_getsibling(int node) @@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling); */ inline int prom_getproplen(int node, const char *prop) { - if((!node) || (!prop)) return -1; - return p1275_cmd ("getproplen", - P1275_ARG(1,P1275_ARG_IN_STRING)| - P1275_INOUT(2, 1), - node, prop); + unsigned long args[6]; + + if (!node || !prop) + return -1; + + args[0] = (unsigned long) "getproplen"; + args[1] = 2; + args[2] = 1; + args[3] = (unsigned int) node; + args[4] = (unsigned long) prop; + args[5] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[5]; } EXPORT_SYMBOL(prom_getproplen); @@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen); inline int prom_getproperty(int node, const char *prop, char *buffer, int bufsize) { + unsigned long args[8]; int plen; plen = prom_getproplen(node, prop); - if ((plen > bufsize) || (plen == 0) || (plen == -1)) { + if ((plen > bufsize) || (plen == 0) || (plen == -1)) return -1; - } else { - /* Ok, things seem all right. */ - return p1275_cmd(prom_getprop_name, - P1275_ARG(1,P1275_ARG_IN_STRING)| - P1275_ARG(2,P1275_ARG_OUT_BUF)| - P1275_INOUT(4, 1), - node, prop, buffer, P1275_SIZE(plen)); - } + + args[0] = (unsigned long) prom_getprop_name; + args[1] = 4; + args[2] = 1; + args[3] = (unsigned int) node; + args[4] = (unsigned long) prop; + args[5] = (unsigned long) buffer; + args[6] = bufsize; + args[7] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[7]; } EXPORT_SYMBOL(prom_getproperty); @@ -110,7 +145,7 @@ inline int prom_getint(int node, const char *prop) { int intprop; - if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) + if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) return intprop; return -1; @@ -126,7 +161,8 @@ int prom_getintdefault(int node, const char *property, int deflt) int retval; retval = prom_getint(node, property); - if(retval == -1) return deflt; + if (retval == -1) + return deflt; return retval; } @@ -138,7 +174,8 @@ int prom_getbool(int node, const char *prop) int retval; retval = prom_getproplen(node, prop); - if(retval == -1) return 0; + if (retval == -1) + return 0; return 1; } EXPORT_SYMBOL(prom_getbool); @@ -152,7 +189,8 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) int len; len = prom_getproperty(node, prop, user_buf, ubuf_size); - if(len != -1) return; + if (len != -1) + return; user_buf[0] = 0; return; } @@ -165,7 +203,8 @@ int prom_nodematch(int node, const char *name) { char namebuf[128]; prom_getproperty(node, "name", namebuf, sizeof(namebuf)); - if(strcmp(namebuf, name) == 0) return 1; + if (strcmp(namebuf, name) == 0) + return 1; return 0; } @@ -191,16 +230,29 @@ int prom_searchsiblings(int node_start, const char *nodename) } EXPORT_SYMBOL(prom_searchsiblings); +static const char *prom_nextprop_name = "nextprop"; + /* Return the first property type for node 'node'. * buffer should be at least 32B in length */ inline char *prom_firstprop(int node, char *buffer) { + unsigned long args[7]; + *buffer = 0; - if(node == -1) return buffer; - p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)| - P1275_INOUT(3, 0), - node, (char *) 0x0, buffer); + if (node == -1) + return buffer; + + args[0] = (unsigned long) prom_nextprop_name; + args[1] = 3; + args[2] = 1; + args[3] = (unsigned int) node; + args[4] = 0; + args[5] = (unsigned long) buffer; + args[6] = (unsigned long) -1; + + p1275_cmd_direct(args); + return buffer; } EXPORT_SYMBOL(prom_firstprop); @@ -211,9 +263,10 @@ EXPORT_SYMBOL(prom_firstprop); */ inline char *prom_nextprop(int node, const char *oprop, char *buffer) { + unsigned long args[7]; char buf[32]; - if(node == -1) { + if (node == -1) { *buffer = 0; return buffer; } @@ -221,10 +274,17 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer) strcpy (buf, oprop); oprop = buf; } - p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)| - P1275_ARG(2,P1275_ARG_OUT_32B)| - P1275_INOUT(3, 0), - node, oprop, buffer); + + args[0] = (unsigned long) prom_nextprop_name; + args[1] = 3; + args[2] = 1; + args[3] = (unsigned int) node; + args[4] = (unsigned long) oprop; + args[5] = (unsigned long) buffer; + args[6] = (unsigned long) -1; + + p1275_cmd_direct(args); + return buffer; } EXPORT_SYMBOL(prom_nextprop); @@ -232,12 +292,19 @@ EXPORT_SYMBOL(prom_nextprop); int prom_finddevice(const char *name) { + unsigned long args[5]; + if (!name) return 0; - return p1275_cmd(prom_finddev_name, - P1275_ARG(0,P1275_ARG_IN_STRING)| - P1275_INOUT(1, 1), - name); + args[0] = (unsigned long) "finddevice"; + args[1] = 1; + args[2] = 1; + args[3] = (unsigned long) name; + args[4] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[4]; } EXPORT_SYMBOL(prom_finddevice); @@ -248,7 +315,7 @@ int prom_node_has_property(int node, const char *prop) *buf = 0; do { prom_nextprop(node, buf, buf); - if(!strcmp(buf, prop)) + if (!strcmp(buf, prop)) return 1; } while (*buf); return 0; @@ -261,6 +328,8 @@ EXPORT_SYMBOL(prom_node_has_property); int prom_setprop(int node, const char *pname, char *value, int size) { + unsigned long args[8]; + if (size == 0) return 0; if ((pname == 0) || (value == 0)) @@ -272,19 +341,37 @@ prom_setprop(int node, const char *pname, char *value, int size) return 0; } #endif - return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)| - P1275_ARG(2,P1275_ARG_IN_BUF)| - P1275_INOUT(4, 1), - node, pname, value, P1275_SIZE(size)); + args[0] = (unsigned long) "setprop"; + args[1] = 4; + args[2] = 1; + args[3] = (unsigned int) node; + args[4] = (unsigned long) pname; + args[5] = (unsigned long) value; + args[6] = size; + args[7] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[7]; } EXPORT_SYMBOL(prom_setprop); inline int prom_inst2pkg(int inst) { + unsigned long args[5]; int node; - node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst); - if (node == -1) return 0; + args[0] = (unsigned long) "instance-to-package"; + args[1] = 1; + args[2] = 1; + args[3] = (unsigned int) inst; + args[4] = (unsigned long) -1; + + p1275_cmd_direct(args); + + node = (int) args[4]; + if (node == -1) + return 0; return node; } @@ -297,17 +384,28 @@ prom_pathtoinode(const char *path) int node, inst; inst = prom_devopen (path); - if (inst == 0) return 0; - node = prom_inst2pkg (inst); - prom_devclose (inst); - if (node == -1) return 0; + if (inst == 0) + return 0; + node = prom_inst2pkg(inst); + prom_devclose(inst); + if (node == -1) + return 0; return node; } int prom_ihandle2path(int handle, char *buffer, int bufsize) { - return p1275_cmd("instance-to-path", - P1275_ARG(1,P1275_ARG_OUT_BUF)| - P1275_INOUT(3, 1), - handle, buffer, P1275_SIZE(bufsize)); + unsigned long args[7]; + + args[0] = (unsigned long) "instance-to-path"; + args[1] = 3; + args[2] = 1; + args[3] = (unsigned int) handle; + args[4] = (unsigned long) buffer; + args[5] = bufsize; + args[6] = (unsigned long) -1; + + p1275_cmd_direct(args); + + return (int) args[6]; } diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index cf8a97f34518..ec8a0eea13f7 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -727,6 +727,9 @@ struct winch { static void free_winch(struct winch *winch, int free_irq_ok) { + if (free_irq_ok) + free_irq(WINCH_IRQ, winch); + list_del(&winch->list); if (winch->pid != -1) @@ -735,8 +738,6 @@ static void free_winch(struct winch *winch, int free_irq_ok) os_close_file(winch->fd); if (winch->stack != 0) free_stack(winch->stack, 0); - if (free_irq_ok) - free_irq(WINCH_IRQ, winch); kfree(winch); } diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 635d16d90a80..9fcf26c5216e 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -160,6 +160,7 @@ struct ubd { struct scatterlist sg[MAX_SG]; struct request *request; int start_sg, end_sg; + sector_t rq_pos; }; #define DEFAULT_COW { \ @@ -184,6 +185,7 @@ struct ubd { .request = NULL, \ .start_sg = 0, \ .end_sg = 0, \ + .rq_pos = 0, \ } /* Protected by ubd_lock */ @@ -1222,7 +1224,6 @@ static void do_ubd_request(struct request_queue *q) { struct io_thread_req *io_req; struct request *req; - sector_t sector; int n; while(1){ @@ -1233,12 +1234,12 @@ static void do_ubd_request(struct request_queue *q) return; dev->request = req; + dev->rq_pos = blk_rq_pos(req); dev->start_sg = 0; dev->end_sg = blk_rq_map_sg(q, req, dev->sg); } req = dev->request; - sector = blk_rq_pos(req); while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; @@ -1250,10 +1251,9 @@ static void do_ubd_request(struct request_queue *q) return; } prepare_request(req, io_req, - (unsigned long long)sector << 9, + (unsigned long long)dev->rq_pos << 9, sg->offset, sg->length, sg_page(sg)); - sector += sg->length >> 9; n = os_write_file(thread_fd, &io_req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ @@ -1266,6 +1266,7 @@ static void do_ubd_request(struct request_queue *q) return; } + dev->rq_pos += sg->length >> 9; dev->start_sg++; } dev->end_sg = 0; diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index e7a6cca667aa..664f94216eb7 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -22,7 +22,7 @@ SECTIONS _text = .; _stext = .; __init_begin = .; - INIT_TEXT_SECTION(PAGE_SIZE) + INIT_TEXT_SECTION(0) . = ALIGN(PAGE_SIZE); .text : diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index dec5678fc17f..6e3359d6a839 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -60,7 +60,7 @@ static inline long long timeval_to_ns(const struct timeval *tv) long long disable_timer(void) { struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } }); - int remain, max = UM_NSEC_PER_SEC / UM_HZ; + long long remain, max = UM_NSEC_PER_SEC / UM_HZ; if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0) printk(UM_KERN_ERR "disable_timer - setitimer failed, " diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 2201e9c20e4a..c1ea9eb04466 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -8,7 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ sysrq.o ksyms.o tls.o -subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o +subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ + lib/rwsem_64.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o ldt-y = ../sys-i386/ldt.o diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4fdb669e8469..cb5a57c61075 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -227,6 +227,11 @@ config X86_32_LAZY_GS config KTIME_SCALAR def_bool X86_32 + +config ARCH_CPU_PROBE_RELEASE + def_bool y + depends on HOTPLUG_CPU + source "init/Kconfig" source "kernel/Kconfig.freezer" @@ -622,7 +627,7 @@ config GART_IOMMU bool "GART IOMMU support" if EMBEDDED default y select SWIOTLB - depends on X86_64 && PCI + depends on X86_64 && PCI && K8_NB ---help--- Support for full DMA access of devices with 32bit memory access only on systems with more than 3GB. This is usually needed for USB, @@ -1236,6 +1241,11 @@ config ARCH_MEMORY_PROBE def_bool X86_64 depends on MEMORY_HOTPLUG +config ILLEGAL_POINTER_VALUE + hex + default 0 if X86_32 + default 0xdead000000000000 if X86_64 + source "mm/Kconfig" config HIGHPTE @@ -2022,7 +2032,7 @@ endif # X86_32 config K8_NB def_bool y - depends on AGP_AMD64 || (X86_64 && (GART_IOMMU || (PCI && NUMA))) + depends on CPU_SUP_AMD && PCI source "drivers/pcmcia/Kconfig" diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index f2824fb8c79c..0e5661033565 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -323,7 +323,7 @@ config X86_L1_CACHE_SHIFT config X86_XADD def_bool y - depends on X86_32 && !M386 + depends on X86_64 || !M386 config X86_PPRO_FENCE bool "PentiumPro memory ordering errata workaround" diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index f9f472462753..14531abdd0ce 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -327,7 +327,6 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) current->mm->free_area_cache = TASK_UNMAPPED_BASE; current->mm->cached_hole_size = 0; - current->mm->mmap = NULL; install_exec_creds(bprm); current->flags &= ~PF_FORKNOEXEC; diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 5294d8446732..4edd8eb425cf 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -50,7 +50,12 @@ /* * Reload arg registers from stack in case ptrace changed them. * We don't reload %eax because syscall_trace_enter() returned - * the value it wants us to use in the table lookup. + * the %rax value we should see. Instead, we just truncate that + * value to 32 bits again as we did on entry from user mode. + * If it's a new value set by user_regset during entry tracing, + * this matches the normal truncation of the user-mode value. + * If it's -1 to make us punt the syscall, then (u32)-1 is still + * an appropriately invalid value. */ .macro LOAD_ARGS32 offset, _r9=0 .if \_r9 @@ -60,6 +65,7 @@ movl \offset+48(%rsp),%edx movl \offset+56(%rsp),%esi movl \offset+64(%rsp),%edi + movl %eax,%eax /* zero extension */ .endm .macro CFI_STARTPROC32 simple @@ -153,7 +159,7 @@ ENTRY(ia32_sysenter_target) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) CFI_REMEMBER_STATE jnz sysenter_tracesys - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys sysenter_do_call: IA32_ARG_FIXUP @@ -195,7 +201,7 @@ sysexit_from_sys_call: movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ call audit_syscall_entry movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys movl %ebx,%edi /* reload 1st syscall arg */ movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ @@ -248,7 +254,7 @@ sysenter_tracesys: call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ jmp sysenter_do_call CFI_ENDPROC @@ -314,7 +320,7 @@ ENTRY(ia32_cstar_target) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) CFI_REMEMBER_STATE jnz cstar_tracesys - cmpl $IA32_NR_syscalls-1,%eax + cmpq $IA32_NR_syscalls-1,%rax ja ia32_badsys cstar_do_call: IA32_ARG_FIXUP 1 @@ -367,7 +373,7 @@ cstar_tracesys: LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ RESTORE_REST xchgl %ebp,%r9d - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ jmp cstar_do_call END(ia32_cstar_target) @@ -425,7 +431,7 @@ ENTRY(ia32_syscall) orl $TS_COMPAT,TI_status(%r10) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) jnz ia32_tracesys - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja ia32_badsys ia32_do_call: IA32_ARG_FIXUP @@ -444,7 +450,7 @@ ia32_tracesys: call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - cmpl $(IA32_NR_syscalls-1),%eax + cmpq $(IA32_NR_syscalls-1),%rax ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ jmp ia32_do_call END(ia32_syscall) diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 2a2cc7a78a81..7beb491de20e 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h @@ -305,6 +305,9 @@ struct amd_iommu { /* capabilities of that IOMMU read from ACPI */ u32 cap; + /* flags read from acpi table */ + u8 acpi_flags; + /* * Capability pointer. There could be more than one IOMMU per PCI * device function if there are more than one AMD IOMMU capability @@ -348,6 +351,15 @@ struct amd_iommu { /* default dma_ops domain for that IOMMU */ struct dma_ops_domain *default_dom; + + /* + * This array is required to work around a potential BIOS bug. + * The BIOS may miss to restore parts of the PCI configuration + * space when the system resumes from S3. The result is that the + * IOMMU does not execute commands anymore which leads to system + * failure. + */ + u32 cache_cfg[4]; }; /* @@ -469,4 +481,10 @@ static inline void amd_iommu_stats_init(void) { } /* some function prototypes */ extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); +static inline bool is_rd890_iommu(struct pci_dev *pdev) +{ + return (pdev->vendor == PCI_VENDOR_ID_ATI) && + (pdev->device == PCI_DEVICE_ID_RD890_IOMMU); +} + #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h index ee1931be6593..9873a5f64676 100644 --- a/arch/x86/include/asm/cmpxchg_32.h +++ b/arch/x86/include/asm/cmpxchg_32.h @@ -17,60 +17,33 @@ struct __xchg_dummy { #define __xg(x) ((struct __xchg_dummy *)(x)) /* - * The semantics of XCHGCMP8B are a bit strange, this is why - * there is a loop and the loading of %%eax and %%edx has to - * be inside. This inlines well in most cases, the cached - * cost is around ~38 cycles. (in the future we might want - * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that - * might have an implicit FPU-save as a cost, so it's not - * clear which path to go.) + * CMPXCHG8B only writes to the target if we had the previous + * value in registers, otherwise it acts as a read and gives us the + * "new previous" value. That is why there is a loop. Preloading + * EDX:EAX is a performance optimization: in the common case it means + * we need only one locked operation. * - * cmpxchg8b must be used with the lock prefix here to allow - * the instruction to be executed atomically, see page 3-102 - * of the instruction set reference 24319102.pdf. We need - * the reader side to see the coherent 64bit value. + * A SIMD/3DNOW!/MMX/FPU 64-bit store here would require at the very + * least an FPU save and/or %cr0.ts manipulation. + * + * cmpxchg8b must be used with the lock prefix here to allow the + * instruction to be executed atomically. We need to have the reader + * side to see the coherent 64bit value. */ -static inline void __set_64bit(unsigned long long *ptr, - unsigned int low, unsigned int high) +static inline void set_64bit(volatile u64 *ptr, u64 value) { + u32 low = value; + u32 high = value >> 32; + u64 prev = *ptr; + asm volatile("\n1:\t" - "movl (%0), %%eax\n\t" - "movl 4(%0), %%edx\n\t" - LOCK_PREFIX "cmpxchg8b (%0)\n\t" + LOCK_PREFIX "cmpxchg8b %0\n\t" "jnz 1b" - : /* no outputs */ - : "D"(ptr), - "b"(low), - "c"(high) - : "ax", "dx", "memory"); + : "=m" (*ptr), "+A" (prev) + : "b" (low), "c" (high) + : "memory"); } -static inline void __set_64bit_constant(unsigned long long *ptr, - unsigned long long value) -{ - __set_64bit(ptr, (unsigned int)value, (unsigned int)(value >> 32)); -} - -#define ll_low(x) *(((unsigned int *)&(x)) + 0) -#define ll_high(x) *(((unsigned int *)&(x)) + 1) - -static inline void __set_64bit_var(unsigned long long *ptr, - unsigned long long value) -{ - __set_64bit(ptr, ll_low(value), ll_high(value)); -} - -#define set_64bit(ptr, value) \ - (__builtin_constant_p((value)) \ - ? __set_64bit_constant((ptr), (value)) \ - : __set_64bit_var((ptr), (value))) - -#define _set_64bit(ptr, value) \ - (__builtin_constant_p(value) \ - ? __set_64bit(ptr, (unsigned int)(value), \ - (unsigned int)((value) >> 32)) \ - : __set_64bit(ptr, ll_low((value)), ll_high((value)))) - /* * Note: no "lock" prefix even on SMP: xchg always implies lock anyway * Note 2: xchg has side effect, so that attribute volatile is necessary, @@ -82,20 +55,20 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, switch (size) { case 1: asm volatile("xchgb %b0,%1" - : "=q" (x) - : "m" (*__xg(ptr)), "0" (x) + : "=q" (x), "+m" (*__xg(ptr)) + : "0" (x) : "memory"); break; case 2: asm volatile("xchgw %w0,%1" - : "=r" (x) - : "m" (*__xg(ptr)), "0" (x) + : "=r" (x), "+m" (*__xg(ptr)) + : "0" (x) : "memory"); break; case 4: asm volatile("xchgl %0,%1" - : "=r" (x) - : "m" (*__xg(ptr)), "0" (x) + : "=r" (x), "+m" (*__xg(ptr)) + : "0" (x) : "memory"); break; } @@ -139,21 +112,21 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long prev; switch (size) { case 1: - asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2" - : "=a"(prev) - : "q"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile(LOCK_PREFIX "cmpxchgb %b2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "q"(new), "0"(old) : "memory"); return prev; case 2: - asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile(LOCK_PREFIX "cmpxchgw %w2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 4: - asm volatile(LOCK_PREFIX "cmpxchgl %1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile(LOCK_PREFIX "cmpxchgl %2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; } @@ -172,21 +145,21 @@ static inline unsigned long __sync_cmpxchg(volatile void *ptr, unsigned long prev; switch (size) { case 1: - asm volatile("lock; cmpxchgb %b1,%2" - : "=a"(prev) - : "q"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("lock; cmpxchgb %b2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "q"(new), "0"(old) : "memory"); return prev; case 2: - asm volatile("lock; cmpxchgw %w1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("lock; cmpxchgw %w2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 4: - asm volatile("lock; cmpxchgl %1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("lock; cmpxchgl %2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; } @@ -200,21 +173,21 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, unsigned long prev; switch (size) { case 1: - asm volatile("cmpxchgb %b1,%2" - : "=a"(prev) - : "q"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("cmpxchgb %b2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "q"(new), "0"(old) : "memory"); return prev; case 2: - asm volatile("cmpxchgw %w1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("cmpxchgw %w2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 4: - asm volatile("cmpxchgl %1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("cmpxchgl %2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; } @@ -226,11 +199,10 @@ static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long new) { unsigned long long prev; - asm volatile(LOCK_PREFIX "cmpxchg8b %3" - : "=A"(prev) + asm volatile(LOCK_PREFIX "cmpxchg8b %1" + : "=A"(prev), "+m" (*__xg(ptr)) : "b"((unsigned long)new), "c"((unsigned long)(new >> 32)), - "m"(*__xg(ptr)), "0"(old) : "memory"); return prev; @@ -241,11 +213,10 @@ static inline unsigned long long __cmpxchg64_local(volatile void *ptr, unsigned long long new) { unsigned long long prev; - asm volatile("cmpxchg8b %3" - : "=A"(prev) + asm volatile("cmpxchg8b %1" + : "=A"(prev), "+m"(*__xg(ptr)) : "b"((unsigned long)new), "c"((unsigned long)(new >> 32)), - "m"(*__xg(ptr)), "0"(old) : "memory"); return prev; diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h index 52de72e0de8c..e8cb051b8681 100644 --- a/arch/x86/include/asm/cmpxchg_64.h +++ b/arch/x86/include/asm/cmpxchg_64.h @@ -8,13 +8,11 @@ #define __xg(x) ((volatile long *)(x)) -static inline void set_64bit(volatile unsigned long *ptr, unsigned long val) +static inline void set_64bit(volatile u64 *ptr, u64 val) { *ptr = val; } -#define _set_64bit set_64bit - /* * Note: no "lock" prefix even on SMP: xchg always implies lock anyway * Note 2: xchg has side effect, so that attribute volatile is necessary, @@ -26,26 +24,26 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, switch (size) { case 1: asm volatile("xchgb %b0,%1" - : "=q" (x) - : "m" (*__xg(ptr)), "0" (x) + : "=q" (x), "+m" (*__xg(ptr)) + : "0" (x) : "memory"); break; case 2: asm volatile("xchgw %w0,%1" - : "=r" (x) - : "m" (*__xg(ptr)), "0" (x) + : "=r" (x), "+m" (*__xg(ptr)) + : "0" (x) : "memory"); break; case 4: asm volatile("xchgl %k0,%1" - : "=r" (x) - : "m" (*__xg(ptr)), "0" (x) + : "=r" (x), "+m" (*__xg(ptr)) + : "0" (x) : "memory"); break; case 8: asm volatile("xchgq %0,%1" - : "=r" (x) - : "m" (*__xg(ptr)), "0" (x) + : "=r" (x), "+m" (*__xg(ptr)) + : "0" (x) : "memory"); break; } @@ -66,27 +64,27 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long prev; switch (size) { case 1: - asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2" - : "=a"(prev) - : "q"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile(LOCK_PREFIX "cmpxchgb %b2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "q"(new), "0"(old) : "memory"); return prev; case 2: - asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile(LOCK_PREFIX "cmpxchgw %w2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 4: - asm volatile(LOCK_PREFIX "cmpxchgl %k1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile(LOCK_PREFIX "cmpxchgl %k2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 8: - asm volatile(LOCK_PREFIX "cmpxchgq %1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile(LOCK_PREFIX "cmpxchgq %2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; } @@ -105,21 +103,27 @@ static inline unsigned long __sync_cmpxchg(volatile void *ptr, unsigned long prev; switch (size) { case 1: - asm volatile("lock; cmpxchgb %b1,%2" - : "=a"(prev) - : "q"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("lock; cmpxchgb %b2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "q"(new), "0"(old) : "memory"); return prev; case 2: - asm volatile("lock; cmpxchgw %w1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("lock; cmpxchgw %w2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 4: - asm volatile("lock; cmpxchgl %1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("lock; cmpxchgl %k2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) + : "memory"); + return prev; + case 8: + asm volatile("lock; cmpxchgq %2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; } @@ -133,27 +137,27 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, unsigned long prev; switch (size) { case 1: - asm volatile("cmpxchgb %b1,%2" - : "=a"(prev) - : "q"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("cmpxchgb %b2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "q"(new), "0"(old) : "memory"); return prev; case 2: - asm volatile("cmpxchgw %w1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("cmpxchgw %w2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 4: - asm volatile("cmpxchgl %k1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("cmpxchgl %k2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; case 8: - asm volatile("cmpxchgq %1,%2" - : "=a"(prev) - : "r"(new), "m"(*__xg(ptr)), "0"(old) + asm volatile("cmpxchgq %2,%1" + : "=a"(prev), "+m"(*__xg(ptr)) + : "r"(new), "0"(old) : "memory"); return prev; } diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index 9a9c7bdc923d..c8c9a74d8ccc 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h @@ -204,7 +204,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -static inline void __user *compat_alloc_user_space(long len) +static inline void __user *arch_compat_alloc_user_space(long len) { struct pt_regs *regs = task_pt_regs(current); return (void __user *)regs->sp - len; diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 9cfc88b97742..1efb1fae606f 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -150,9 +150,10 @@ #define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */ #define X86_FEATURE_OSVW (6*32+ 9) /* OS Visible Workaround */ #define X86_FEATURE_IBS (6*32+10) /* Instruction Based Sampling */ -#define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */ +#define X86_FEATURE_XOP (6*32+11) /* extended AVX instructions */ #define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */ #define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */ +#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */ /* * Auxiliary flags: Linux defined - For features scattered in various diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 14f9890eb495..c22a1648113d 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -82,6 +82,9 @@ enum fixed_addresses { #endif FIX_DBGP_BASE, FIX_EARLYCON_MEM_BASE, +#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT + FIX_OHCI1394_BASE, +#endif #ifdef CONFIG_X86_LOCAL_APIC FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ #endif @@ -126,9 +129,6 @@ enum fixed_addresses { FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 - (__end_of_permanent_fixed_addresses & 255), FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1, -#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT - FIX_OHCI1394_BASE, -#endif #ifdef CONFIG_X86_32 FIX_WP_TEST, #endif diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 73739322b6d0..6a63b86c64a1 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -172,6 +172,7 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size) extern void iounmap(volatile void __iomem *addr); +extern void set_iounmap_nonlazy(void); #ifdef CONFIG_X86_32 # include "io_32.h" diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 7c7c16cde1f8..5f61f6e0ffdd 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -160,6 +160,7 @@ extern int io_apic_get_redir_entries(int ioapic); struct io_apic_irq_attr; extern int io_apic_set_pci_routing(struct device *dev, int irq, struct io_apic_irq_attr *irq_attr); +void setup_IO_APIC_irq_extra(u32 gsi); extern int (*ioapic_renumber_irq)(int ioapic, int irq); extern void ioapic_init_mappings(void); extern void ioapic_insert_resources(void); diff --git a/arch/x86/include/asm/k8.h b/arch/x86/include/asm/k8.h index c2d1f3b58e5f..f0746f46990d 100644 --- a/arch/x86/include/asm/k8.h +++ b/arch/x86/include/asm/k8.h @@ -13,11 +13,16 @@ extern void k8_flush_garts(void); extern int k8_scan_nodes(unsigned long start, unsigned long end); #ifdef CONFIG_K8_NB +extern int num_k8_northbridges; + static inline struct pci_dev *node_to_k8_nb_misc(int node) { return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL; } + #else +#define num_k8_northbridges 0 + static inline struct pci_dev *node_to_k8_nb_misc(int node) { return NULL; diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 7c18e1230f54..5ed59ec92534 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -54,13 +54,23 @@ struct x86_emulate_ctxt; struct x86_emulate_ops { /* * read_std: Read bytes of standard (non-emulated/special) memory. - * Used for instruction fetch, stack operations, and others. + * Used for descriptor reading. * @addr: [IN ] Linear address from which to read. * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory. */ int (*read_std)(unsigned long addr, void *val, - unsigned int bytes, struct kvm_vcpu *vcpu); + unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); + + /* + * fetch: Read bytes of standard (non-emulated/special) memory. + * Used for instruction fetch. + * @addr: [IN ] Linear address from which to read. + * @val: [OUT] Value read from memory, zero-extended to 'u_long'. + * @bytes: [IN ] Number of bytes to read from memory. + */ + int (*fetch)(unsigned long addr, void *val, + unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); /* * read_emulated: Read bytes from emulated/special memory area. @@ -168,6 +178,7 @@ struct x86_emulate_ctxt { /* Execution mode, passed to the emulator. */ #define X86EMUL_MODE_REAL 0 /* Real mode. */ +#define X86EMUL_MODE_VM86 1 /* Virtual 8086 mode. */ #define X86EMUL_MODE_PROT16 2 /* 16-bit protected mode. */ #define X86EMUL_MODE_PROT32 4 /* 32-bit protected mode. */ #define X86EMUL_MODE_PROT64 8 /* 64-bit (long) mode. */ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d759a1f55084..600807b3d365 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -193,6 +193,7 @@ union kvm_mmu_page_role { unsigned invalid:1; unsigned cr4_pge:1; unsigned nxe:1; + unsigned cr0_wp:1; }; }; @@ -256,7 +257,8 @@ struct kvm_mmu { void (*new_cr3)(struct kvm_vcpu *vcpu); int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err); void (*free)(struct kvm_vcpu *vcpu); - gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva); + gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access, + u32 *error); void (*prefetch_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page); int (*sync_page)(struct kvm_vcpu *vcpu, @@ -601,8 +603,7 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value); void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); -int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, - int type_bits, int seg); +int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason); @@ -645,6 +646,10 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu); int kvm_mmu_load(struct kvm_vcpu *vcpu); void kvm_mmu_unload(struct kvm_vcpu *vcpu); void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu); +gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); +gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); +gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); +gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); int kvm_emulate_hypercall(struct kvm_vcpu *vcpu); @@ -658,6 +663,7 @@ void kvm_disable_tdp(void); int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); int complete_pio(struct kvm_vcpu *vcpu); +bool kvm_check_iopl(struct kvm_vcpu *vcpu); struct kvm_memory_slot *gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn); @@ -668,20 +674,6 @@ static inline struct kvm_mmu_page *page_header(hpa_t shadow_page) return (struct kvm_mmu_page *)page_private(page); } -static inline u16 kvm_read_fs(void) -{ - u16 seg; - asm("mov %%fs, %0" : "=g"(seg)); - return seg; -} - -static inline u16 kvm_read_gs(void) -{ - u16 seg; - asm("mov %%gs, %0" : "=g"(seg)); - return seg; -} - static inline u16 kvm_read_ldt(void) { u16 ldt; @@ -689,16 +681,6 @@ static inline u16 kvm_read_ldt(void) return ldt; } -static inline void kvm_load_fs(u16 sel) -{ - asm("mov %0, %%fs" : : "rm"(sel)); -} - -static inline void kvm_load_gs(u16 sel) -{ - asm("mov %0, %%gs" : : "rm"(sel)); -} - static inline void kvm_load_ldt(u16 sel) { asm("lldt %0" : : "rm"(sel)); diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 4ffe09b2ad75..a7e502fdb16c 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -104,6 +104,9 @@ #define MSR_AMD64_PATCH_LEVEL 0x0000008b #define MSR_AMD64_NB_CFG 0xc001001f #define MSR_AMD64_PATCH_LOADER 0xc0010020 +#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 +#define MSR_AMD64_OSVW_STATUS 0xc0010141 +#define MSR_AMD64_DC_CFG 0xc0011022 #define MSR_AMD64_IBSFETCHCTL 0xc0011030 #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 #define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 @@ -123,6 +126,7 @@ #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff #define FAM10H_MMIO_CONF_BASE_SHIFT 20 +#define MSR_FAM10H_NODE_ID 0xc001100c /* K8 MSRs */ #define MSR_K8_TOP_MEM1 0xc001001a @@ -195,8 +199,9 @@ #define MSR_IA32_EBL_CR_POWERON 0x0000002a #define MSR_IA32_FEATURE_CONTROL 0x0000003a -#define FEATURE_CONTROL_LOCKED (1<<0) -#define FEATURE_CONTROL_VMXON_ENABLED (1<<2) +#define FEATURE_CONTROL_LOCKED (1<<0) +#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) +#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) #define MSR_IA32_APICBASE 0x0000001b #define MSR_IA32_APICBASE_BSP (1<<8) diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index 0e8c2a0fd922..271de94c3810 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h @@ -22,6 +22,11 @@ static inline void paravirt_release_pmd(unsigned long pfn) {} static inline void paravirt_release_pud(unsigned long pfn) {} #endif +/* + * Flags to use when allocating a user page table page. + */ +extern gfp_t __userpte_alloc_gfp; + /* * Allocate and free page tables. */ diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index 01fd9461d323..750f1bf1fab1 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h @@ -27,6 +27,7 @@ struct mm_struct; struct vm_area_struct; extern pgd_t swapper_pg_dir[1024]; +extern pgd_t trampoline_pg_dir[1024]; static inline void pgtable_cache_init(void) { } static inline void check_pgt_cache(void) { } diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index ca7517d33776..606ede126972 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h @@ -41,6 +41,7 @@ #include #include #include +#include struct rwsem_waiter; @@ -55,17 +56,28 @@ extern asmregparm struct rw_semaphore * /* * the semaphore definition + * + * The bias values and the counter type limits the number of + * potential readers/writers to 32767 for 32 bits and 2147483647 + * for 64 bits. */ -#define RWSEM_UNLOCKED_VALUE 0x00000000 -#define RWSEM_ACTIVE_BIAS 0x00000001 -#define RWSEM_ACTIVE_MASK 0x0000ffff -#define RWSEM_WAITING_BIAS (-0x00010000) +#ifdef CONFIG_X86_64 +# define RWSEM_ACTIVE_MASK 0xffffffffL +#else +# define RWSEM_ACTIVE_MASK 0x0000ffffL +#endif + +#define RWSEM_UNLOCKED_VALUE 0x00000000L +#define RWSEM_ACTIVE_BIAS 0x00000001L +#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) +typedef signed long rwsem_count_t; + struct rw_semaphore { - signed long count; + rwsem_count_t count; spinlock_t wait_lock; struct list_head wait_list; #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -105,7 +117,7 @@ do { \ static inline void __down_read(struct rw_semaphore *sem) { asm volatile("# beginning down_read\n\t" - LOCK_PREFIX " incl (%%eax)\n\t" + LOCK_PREFIX _ASM_INC "(%1)\n\t" /* adds 0x00000001, returns the old value */ " jns 1f\n" " call call_rwsem_down_read_failed\n" @@ -121,14 +133,14 @@ static inline void __down_read(struct rw_semaphore *sem) */ static inline int __down_read_trylock(struct rw_semaphore *sem) { - __s32 result, tmp; + rwsem_count_t result, tmp; asm volatile("# beginning __down_read_trylock\n\t" - " movl %0,%1\n\t" + " mov %0,%1\n\t" "1:\n\t" - " movl %1,%2\n\t" - " addl %3,%2\n\t" + " mov %1,%2\n\t" + " add %3,%2\n\t" " jle 2f\n\t" - LOCK_PREFIX " cmpxchgl %2,%0\n\t" + LOCK_PREFIX " cmpxchg %2,%0\n\t" " jnz 1b\n\t" "2:\n\t" "# ending __down_read_trylock\n\t" @@ -143,13 +155,13 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) */ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) { - int tmp; + rwsem_count_t tmp; tmp = RWSEM_ACTIVE_WRITE_BIAS; asm volatile("# beginning down_write\n\t" - LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" + LOCK_PREFIX " xadd %1,(%2)\n\t" /* subtract 0x0000ffff, returns the old value */ - " testl %%edx,%%edx\n\t" + " test %1,%1\n\t" /* was the count 0 before? */ " jz 1f\n" " call call_rwsem_down_write_failed\n" @@ -170,9 +182,9 @@ static inline void __down_write(struct rw_semaphore *sem) */ static inline int __down_write_trylock(struct rw_semaphore *sem) { - signed long ret = cmpxchg(&sem->count, - RWSEM_UNLOCKED_VALUE, - RWSEM_ACTIVE_WRITE_BIAS); + rwsem_count_t ret = cmpxchg(&sem->count, + RWSEM_UNLOCKED_VALUE, + RWSEM_ACTIVE_WRITE_BIAS); if (ret == RWSEM_UNLOCKED_VALUE) return 1; return 0; @@ -183,9 +195,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) */ static inline void __up_read(struct rw_semaphore *sem) { - __s32 tmp = -RWSEM_ACTIVE_READ_BIAS; + rwsem_count_t tmp = -RWSEM_ACTIVE_READ_BIAS; asm volatile("# beginning __up_read\n\t" - LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" + LOCK_PREFIX " xadd %1,(%2)\n\t" /* subtracts 1, returns the old value */ " jns 1f\n\t" " call call_rwsem_wake\n" @@ -201,18 +213,18 @@ static inline void __up_read(struct rw_semaphore *sem) */ static inline void __up_write(struct rw_semaphore *sem) { + rwsem_count_t tmp; asm volatile("# beginning __up_write\n\t" - " movl %2,%%edx\n\t" - LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" + LOCK_PREFIX " xadd %1,(%2)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ " jz 1f\n" " call call_rwsem_wake\n" "1:\n\t" "# ending __up_write\n" - : "+m" (sem->count) - : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS) - : "memory", "cc", "edx"); + : "+m" (sem->count), "=d" (tmp) + : "a" (sem), "1" (-RWSEM_ACTIVE_WRITE_BIAS) + : "memory", "cc"); } /* @@ -221,33 +233,38 @@ static inline void __up_write(struct rw_semaphore *sem) static inline void __downgrade_write(struct rw_semaphore *sem) { asm volatile("# beginning __downgrade_write\n\t" - LOCK_PREFIX " addl %2,(%%eax)\n\t" - /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ + LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t" + /* + * transitions 0xZZZZ0001 -> 0xYYYY0001 (i386) + * 0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 (x86_64) + */ " jns 1f\n\t" " call call_rwsem_downgrade_wake\n" "1:\n\t" "# ending __downgrade_write\n" : "+m" (sem->count) - : "a" (sem), "i" (-RWSEM_WAITING_BIAS) + : "a" (sem), "er" (-RWSEM_WAITING_BIAS) : "memory", "cc"); } /* * implement atomic add functionality */ -static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) +static inline void rwsem_atomic_add(rwsem_count_t delta, + struct rw_semaphore *sem) { - asm volatile(LOCK_PREFIX "addl %1,%0" + asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0" : "+m" (sem->count) - : "ir" (delta)); + : "er" (delta)); } /* * implement exchange and add functionality */ -static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) +static inline rwsem_count_t rwsem_atomic_update(rwsem_count_t delta, + struct rw_semaphore *sem) { - int tmp = delta; + rwsem_count_t tmp = delta; asm volatile(LOCK_PREFIX "xadd %0,%1" : "+r" (tmp), "+m" (sem->count) diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 1e796782cd7b..4c2f63c7fc1b 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -50,7 +50,7 @@ struct smp_ops { void (*smp_prepare_cpus)(unsigned max_cpus); void (*smp_cpus_done)(unsigned max_cpus); - void (*smp_send_stop)(void); + void (*stop_other_cpus)(int wait); void (*smp_send_reschedule)(int cpu); int (*cpu_up)(unsigned cpu); @@ -73,7 +73,12 @@ extern struct smp_ops smp_ops; static inline void smp_send_stop(void) { - smp_ops.smp_send_stop(); + smp_ops.stop_other_cpus(0); +} + +static inline void stop_other_cpus(void) +{ + smp_ops.stop_other_cpus(1); } static inline void smp_prepare_boot_cpu(void) @@ -135,6 +140,8 @@ int native_cpu_disable(void); void native_cpu_die(unsigned int cpu); void native_play_dead(void); void play_dead_common(void); +void wbinvd_on_cpu(int cpu); +int wbinvd_on_all_cpus(void); void native_send_call_func_ipi(const struct cpumask *mask); void native_send_call_func_single_ipi(int cpu); @@ -147,6 +154,13 @@ static inline int num_booting_cpus(void) { return cpumask_weight(cpu_callout_mask); } +#else /* !CONFIG_SMP */ +#define wbinvd_on_cpu(cpu) wbinvd() +static inline int wbinvd_on_all_cpus(void) +{ + wbinvd(); + return 0; +} #endif /* CONFIG_SMP */ extern unsigned disabled_cpus __cpuinitdata; diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h index 48dcfa62ea07..fd921c3a6841 100644 --- a/arch/x86/include/asm/suspend_32.h +++ b/arch/x86/include/asm/suspend_32.h @@ -15,6 +15,8 @@ static inline int arch_prepare_suspend(void) { return 0; } struct saved_context { u16 es, fs, gs, ss; unsigned long cr0, cr2, cr3, cr4; + u64 misc_enable; + bool misc_enable_saved; struct desc_ptr gdt; struct desc_ptr idt; u16 ldt; diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h index 06284f42b759..8d942afae681 100644 --- a/arch/x86/include/asm/suspend_64.h +++ b/arch/x86/include/asm/suspend_64.h @@ -27,6 +27,8 @@ struct saved_context { u16 ds, es, fs, gs, ss; unsigned long gs_base, gs_kernel_base, fs_base; unsigned long cr0, cr2, cr3, cr4, cr8; + u64 misc_enable; + bool misc_enable_saved; unsigned long efer; u16 gdt_pad; u16 gdt_limit; diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index f08f97374892..e0fbf294536c 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -449,7 +449,7 @@ void stop_this_cpu(void *dummy); * * (Could use an alternative three way for this if there was one.) */ -static inline void rdtsc_barrier(void) +static __always_inline void rdtsc_barrier(void) { alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h index 90f06c25221d..ebace684c476 100644 --- a/arch/x86/include/asm/trampoline.h +++ b/arch/x86/include/asm/trampoline.h @@ -13,15 +13,18 @@ extern unsigned char *trampoline_base; extern unsigned long init_rsp; extern unsigned long initial_code; +extern unsigned long initial_page_table; extern unsigned long initial_gs; #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) #define TRAMPOLINE_BASE 0x6000 extern unsigned long setup_trampoline(void); +extern void __init setup_trampoline_page_table(void); extern void __init reserve_trampoline_memory(void); #else -static inline void reserve_trampoline_memory(void) {}; +static inline void setup_trampoline_page_table(void) {} +static inline void reserve_trampoline_memory(void) {} #endif /* CONFIG_X86_TRAMPOLINE */ #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index c0427295e8f5..1ca132fc0d03 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -59,5 +59,7 @@ extern void check_tsc_sync_source(int cpu); extern void check_tsc_sync_target(void); extern int notsc_setup(char *); +extern void save_sched_clock_state(void); +extern void restore_sched_clock_state(void); #endif /* _ASM_X86_TSC_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index d8e5d0cdd678..d1911abac180 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -11,6 +11,8 @@ ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_tsc.o = -pg CFLAGS_REMOVE_rtc.o = -pg CFLAGS_REMOVE_paravirt-spinlocks.o = -pg +CFLAGS_REMOVE_pvclock.o = -pg +CFLAGS_REMOVE_kvmclock.o = -pg CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 67e929b89875..23c2da87df19 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -446,6 +446,12 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) { *irq = gsi; + +#ifdef CONFIG_X86_IO_APIC + if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) + setup_IO_APIC_irq_extra(gsi); +#endif + return 0; } @@ -473,7 +479,8 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); } #endif - acpi_gsi_to_irq(plat_gsi, &irq); + irq = plat_gsi; + return irq; } @@ -1184,9 +1191,6 @@ static void __init acpi_process_madt(void) if (!error) { acpi_lapic = 1; -#ifdef CONFIG_X86_BIGSMP - generic_bigsmp_probe(); -#endif /* * Parse MADT IO-APIC entries */ @@ -1196,8 +1200,6 @@ static void __init acpi_process_madt(void) acpi_ioapic = 1; smp_found_config = 1; - if (apic->setup_apic_routing) - apic->setup_apic_routing(); } } if (error == -EINVAL) { @@ -1346,14 +1348,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), }, }, - { - .callback = force_acpi_ht, - .ident = "ASUS P2B-DS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), - }, - }, { .callback = force_acpi_ht, .ident = "ASUS CUR-DLS", diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index 2e837f5080fe..fb7a5f052e2b 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -145,6 +145,15 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, percpu_entry->states[cx->index].eax = cx->address; percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK; } + + /* + * For _CST FFH on Intel, if GAS.access_size bit 1 is cleared, + * then we should skip checking BM_STS for this C-state. + * ref: "Intel Processor Vendor-Specific ACPI Interface Specification" + */ + if ((c->x86_vendor == X86_VENDOR_INTEL) && !(reg->access_size & 0x2)) + cx->bm_sts_skip = 1; + return retval; } EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 23fc9fe1625f..7cd33f75a69c 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -544,7 +544,7 @@ static void flush_devices_by_domain(struct protection_domain *domain) for (i = 0; i <= amd_iommu_last_bdf; ++i) { if ((domain == NULL && amd_iommu_pd_table[i] == NULL) || - (amd_iommu_pd_table[i] != domain)) + (domain != NULL && amd_iommu_pd_table[i] != domain)) continue; iommu = amd_iommu_rlookup_table[i]; @@ -1688,6 +1688,7 @@ static void __unmap_single(struct amd_iommu *iommu, size_t size, int dir) { + dma_addr_t flush_addr; dma_addr_t i, start; unsigned int pages; @@ -1695,6 +1696,7 @@ static void __unmap_single(struct amd_iommu *iommu, (dma_addr + size > dma_dom->aperture_size)) return; + flush_addr = dma_addr; pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); dma_addr &= PAGE_MASK; start = dma_addr; @@ -1709,7 +1711,7 @@ static void __unmap_single(struct amd_iommu *iommu, dma_ops_free_addresses(dma_dom, dma_addr, pages); if (amd_iommu_unmap_flush || dma_dom->need_flush) { - iommu_flush_pages(iommu, dma_dom->domain.id, dma_addr, size); + iommu_flush_pages(iommu, dma_dom->domain.id, flush_addr, size); dma_dom->need_flush = false; } } @@ -2239,9 +2241,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) free_pagetable(domain); - domain_id_free(domain->id); - - kfree(domain); + protection_domain_free(domain); dom->priv = NULL; } diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 362ab88c73ac..400be996de7b 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -622,6 +622,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu) iommu->last_device = calc_devid(MMIO_GET_BUS(range), MMIO_GET_LD(range)); iommu->evt_msi_num = MMIO_MSI_NUM(misc); + + if (is_rd890_iommu(iommu->dev)) { + pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]); + pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]); + pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]); + pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]); + } } /* @@ -639,29 +646,9 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, struct ivhd_entry *e; /* - * First set the recommended feature enable bits from ACPI - * into the IOMMU control registers + * First save the recommended feature enable bits from ACPI */ - h->flags & IVHD_FLAG_HT_TUN_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : - iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); - - h->flags & IVHD_FLAG_PASSPW_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : - iommu_feature_disable(iommu, CONTROL_PASSPW_EN); - - h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : - iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); - - h->flags & IVHD_FLAG_ISOC_EN_MASK ? - iommu_feature_enable(iommu, CONTROL_ISOC_EN) : - iommu_feature_disable(iommu, CONTROL_ISOC_EN); - - /* - * make IOMMU memory accesses cache coherent - */ - iommu_feature_enable(iommu, CONTROL_COHERENT_EN); + iommu->acpi_flags = h->flags; /* * Done. Now parse the device entries @@ -1089,6 +1076,40 @@ static void init_device_table(void) } } +static void iommu_init_flags(struct amd_iommu *iommu) +{ + iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : + iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); + + iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : + iommu_feature_disable(iommu, CONTROL_PASSPW_EN); + + iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : + iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); + + iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ? + iommu_feature_enable(iommu, CONTROL_ISOC_EN) : + iommu_feature_disable(iommu, CONTROL_ISOC_EN); + + /* + * make IOMMU memory accesses cache coherent + */ + iommu_feature_enable(iommu, CONTROL_COHERENT_EN); +} + +static void iommu_apply_quirks(struct amd_iommu *iommu) +{ + if (is_rd890_iommu(iommu->dev)) { + pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]); + pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]); + pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]); + pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]); + } +} + /* * This function finally enables all IOMMUs found in the system after * they have been initialized @@ -1099,6 +1120,8 @@ static void enable_iommus(void) for_each_iommu(iommu) { iommu_disable(iommu); + iommu_apply_quirks(iommu); + iommu_init_flags(iommu); iommu_set_device_table(iommu); iommu_enable_command_buffer(iommu); iommu_enable_event_buffer(iommu); @@ -1284,6 +1307,8 @@ int __init amd_iommu_init(void) if (ret) goto free; + enable_iommus(); + if (iommu_pass_through) ret = amd_iommu_init_passthrough(); else @@ -1294,8 +1319,6 @@ int __init amd_iommu_init(void) amd_iommu_init_api(); - enable_iommus(); - if (iommu_pass_through) goto out; @@ -1314,6 +1337,8 @@ int __init amd_iommu_init(void) return ret; free: + disable_iommus(); + free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, get_order(MAX_DOMAIN_ID/8)); diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 128111d8ffe0..082089ec5594 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -389,6 +389,7 @@ void __init gart_iommu_hole_init(void) for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) { int bus; int dev_base, dev_limit; + u32 ctl; bus = bus_dev_ranges[i].bus; dev_base = bus_dev_ranges[i].dev_base; @@ -401,7 +402,19 @@ void __init gart_iommu_hole_init(void) iommu_detected = 1; gart_iommu_aperture = 1; - aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7; + ctl = read_pci_config(bus, slot, 3, + AMD64_GARTAPERTURECTL); + + /* + * Before we do anything else disable the GART. It may + * still be enabled if we boot into a crash-kernel here. + * Reconfiguring the GART while it is enabled could have + * unknown side-effects. + */ + ctl &= ~GARTEN; + write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl); + + aper_order = (ctl >> 1) & 7; aper_size = (32 * 1024 * 1024) << aper_order; aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff; aper_base <<= 25; diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index c86dbcf39e8d..6702ab74c58c 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -51,6 +51,7 @@ #include #include #include +#include unsigned int num_processors; @@ -941,7 +942,7 @@ void disable_local_APIC(void) unsigned int value; /* APIC hasn't been mapped yet */ - if (!apic_phys) + if (!x2apic_mode && !apic_phys) return; clear_local_APIC(); @@ -1172,8 +1173,13 @@ static void __cpuinit lapic_setup_esr(void) */ void __cpuinit setup_local_APIC(void) { - unsigned int value; - int i, j; + unsigned int value, queued; + int i, j, acked = 0; + unsigned long long tsc = 0, ntsc; + long long max_loops = cpu_khz; + + if (cpu_has_tsc) + rdtscll(tsc); if (disable_apic) { arch_disable_smp_support(); @@ -1225,13 +1231,32 @@ void __cpuinit setup_local_APIC(void) * the interrupt. Hence a vector might get locked. It was noticed * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. */ - for (i = APIC_ISR_NR - 1; i >= 0; i--) { - value = apic_read(APIC_ISR + i*0x10); - for (j = 31; j >= 0; j--) { - if (value & (1<= 0; i--) + queued |= apic_read(APIC_IRR + i*0x10); + + for (i = APIC_ISR_NR - 1; i >= 0; i--) { + value = apic_read(APIC_ISR + i*0x10); + for (j = 31; j >= 0; j--) { + if (value & (1< 256) { + printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n", + acked); + break; + } + if (cpu_has_tsc) { + rdtscll(ntsc); + max_loops = (cpu_khz << 10) - (ntsc - tsc); + } else + max_loops--; + } while (queued && max_loops > 0); + WARN_ON(max_loops <= 0); /* * Now that we are all set up, enable the APIC @@ -1664,8 +1689,8 @@ int __init APIC_init_uniprocessor(void) } #endif +#ifndef CONFIG_SMP enable_IR_x2apic(); -#ifdef CONFIG_X86_64 default_setup_apic_routing(); #endif @@ -1915,18 +1940,6 @@ void __cpuinit generic_processor_info(int apicid, int version) if (apicid > max_physical_apicid) max_physical_apicid = apicid; -#ifdef CONFIG_X86_32 - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_INTEL: - if (num_processors > 8) - def_to_bigsmp = 1; - break; - case X86_VENDOR_AMD: - if (max_physical_apicid >= 8) - def_to_bigsmp = 1; - } -#endif - #if defined(CONFIG_SMP) || defined(CONFIG_X86_64) early_per_cpu(x86_cpu_to_apicid, cpu) = apicid; early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index c107e837ed7d..d850eeb19243 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -332,14 +332,19 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc, old_cfg = old_desc->chip_data; - memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); + cfg->vector = old_cfg->vector; + cfg->move_in_progress = old_cfg->move_in_progress; + cpumask_copy(cfg->domain, old_cfg->domain); + cpumask_copy(cfg->old_domain, old_cfg->old_domain); init_copy_irq_2_pin(old_cfg, cfg, node); } -static void free_irq_cfg(struct irq_cfg *old_cfg) +static void free_irq_cfg(struct irq_cfg *cfg) { - kfree(old_cfg); + free_cpumask_var(cfg->domain); + free_cpumask_var(cfg->old_domain); + kfree(cfg); } void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) @@ -1405,6 +1410,7 @@ int setup_ioapic_entry(int apic_id, int irq, irte.dlvry_mode = apic->irq_delivery_mode; irte.vector = vector; irte.dest_id = IRTE_DEST(destination); + irte.redir_hint = 1; /* Set source-id of interrupt request */ set_ioapic_sid(&irte, apic_id); @@ -1484,7 +1490,7 @@ static struct { static void __init setup_IO_APIC_irqs(void) { - int apic_id = 0, pin, idx, irq; + int apic_id, pin, idx, irq; int notcon = 0; struct irq_desc *desc; struct irq_cfg *cfg; @@ -1492,14 +1498,7 @@ static void __init setup_IO_APIC_irqs(void) apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); -#ifdef CONFIG_ACPI - if (!acpi_disabled && acpi_ioapic) { - apic_id = mp_find_ioapic(0); - if (apic_id < 0) - apic_id = 0; - } -#endif - + for (apic_id = 0; apic_id < nr_ioapics; apic_id++) for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { idx = find_irq_entry(apic_id, pin, mp_INT); if (idx == -1) { @@ -1521,6 +1520,9 @@ static void __init setup_IO_APIC_irqs(void) irq = pin_2_irq(idx, apic_id, pin); + if ((apic_id > 0) && (irq > 16)) + continue; + /* * Skip the timer IRQ if there's a quirk handler * installed and if it returns 1: @@ -1549,6 +1551,56 @@ static void __init setup_IO_APIC_irqs(void) " (apicid-pin) not connected\n"); } +/* + * for the gsit that is not in first ioapic + * but could not use acpi_register_gsi() + * like some special sci in IBM x3330 + */ +void setup_IO_APIC_irq_extra(u32 gsi) +{ + int apic_id = 0, pin, idx, irq; + int node = cpu_to_node(boot_cpu_id); + struct irq_desc *desc; + struct irq_cfg *cfg; + + /* + * Convert 'gsi' to 'ioapic.pin'. + */ + apic_id = mp_find_ioapic(gsi); + if (apic_id < 0) + return; + + pin = mp_find_ioapic_pin(apic_id, gsi); + idx = find_irq_entry(apic_id, pin, mp_INT); + if (idx == -1) + return; + + irq = pin_2_irq(idx, apic_id, pin); +#ifdef CONFIG_SPARSE_IRQ + desc = irq_to_desc(irq); + if (desc) + return; +#endif + desc = irq_to_desc_alloc_node(irq, node); + if (!desc) { + printk(KERN_INFO "can not get irq_desc for %d\n", irq); + return; + } + + cfg = desc->chip_data; + add_pin_to_irq_node(cfg, node, apic_id, pin); + + if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { + pr_debug("Pin %d-%d already programmed\n", + mp_ioapics[apic_id].apicid, pin); + return; + } + set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed); + + setup_IO_APIC_irq(apic_id, pin, irq, desc, + irq_trigger(idx), irq_polarity(idx)); +} + /* * Set up the timer pin, possibly with the 8259A-master behind. */ @@ -1690,6 +1742,8 @@ __apicdebuginit(void) print_IO_APIC(void) struct irq_pin_list *entry; cfg = desc->chip_data; + if (!cfg) + continue; entry = cfg->irq_2_pin; if (!entry) continue; @@ -3165,12 +3219,9 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) } spin_unlock_irqrestore(&vector_lock, flags); - if (irq > 0) { - dynamic_irq_init(irq); - /* restore it, in case dynamic_irq_init clear it */ - if (desc_new) - desc_new->chip_data = cfg_new; - } + if (irq > 0) + dynamic_irq_init_keep_chip_data(irq); + return irq; } @@ -3193,17 +3244,12 @@ void destroy_irq(unsigned int irq) { unsigned long flags; struct irq_cfg *cfg; - struct irq_desc *desc; - /* store it, in case dynamic_irq_cleanup clear it */ - desc = irq_to_desc(irq); - cfg = desc->chip_data; - dynamic_irq_cleanup(irq); - /* connect back irq_cfg */ - desc->chip_data = cfg; + dynamic_irq_cleanup_keep_chip_data(irq); free_irte(irq); spin_lock_irqsave(&vector_lock, flags); + cfg = irq_to_desc(irq)->chip_data; __clear_irq_vector(irq, cfg); spin_unlock_irqrestore(&vector_lock, flags); } @@ -3244,6 +3290,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms irte.dlvry_mode = apic->irq_delivery_mode; irte.vector = cfg->vector; irte.dest_id = IRTE_DEST(dest); + irte.redir_hint = 1; /* Set source-id of interrupt request */ set_msi_sid(&irte, pdev); @@ -3298,7 +3345,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) cfg = desc->chip_data; - read_msi_msg_desc(desc, &msg); + get_cached_msi_msg_desc(desc, &msg); msg.data &= ~MSI_DATA_VECTOR_MASK; msg.data |= MSI_DATA_VECTOR(cfg->vector); @@ -4041,27 +4088,23 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) #ifdef CONFIG_SMP void __init setup_ioapic_dest(void) { - int pin, ioapic = 0, irq, irq_entry; + int pin, ioapic, irq, irq_entry; struct irq_desc *desc; const struct cpumask *mask; if (skip_ioapic_setup == 1) return; -#ifdef CONFIG_ACPI - if (!acpi_disabled && acpi_ioapic) { - ioapic = mp_find_ioapic(0); - if (ioapic < 0) - ioapic = 0; - } -#endif - + for (ioapic = 0; ioapic < nr_ioapics; ioapic++) for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { irq_entry = find_irq_entry(ioapic, pin, mp_INT); if (irq_entry == -1) continue; irq = pin_2_irq(irq_entry, ioapic, pin); + if ((ioapic > 0) && (irq > 16)) + continue; + desc = irq_to_desc(irq); /* diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 0c0182cc947d..88b9d22c8432 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -53,6 +53,31 @@ static int __init print_ipi_mode(void) late_initcall(print_ipi_mode); void default_setup_apic_routing(void) +{ + int version = apic_version[boot_cpu_physical_apicid]; + + if (num_possible_cpus() > 8) { + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_INTEL: + if (!APIC_XAPIC(version)) { + def_to_bigsmp = 0; + break; + } + /* If P4 and above fall through */ + case X86_VENDOR_AMD: + def_to_bigsmp = 1; + } + } + +#ifdef CONFIG_X86_BIGSMP + generic_bigsmp_probe(); +#endif + + if (apic->setup_apic_routing) + apic->setup_apic_routing(); +} + +void setup_apic_flat_routing(void) { #ifdef CONFIG_X86_IO_APIC printk(KERN_INFO @@ -103,7 +128,7 @@ struct apic apic_default = { .init_apic_ldr = default_init_apic_ldr, .ioapic_phys_id_map = default_ioapic_phys_id_map, - .setup_apic_routing = default_setup_apic_routing, + .setup_apic_routing = setup_apic_flat_routing, .multi_timer_check = NULL, .apicid_to_node = default_apicid_to_node, .cpu_to_logical_apicid = default_cpu_to_logical_apicid, diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index c4cbd3080c1c..4c56f544f167 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -67,17 +67,8 @@ void __init default_setup_apic_routing(void) } #endif - if (apic == &apic_flat) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_INTEL: - if (num_processors > 8) - apic = &apic_physflat; - break; - case X86_VENDOR_AMD: - if (max_physical_apicid >= 8) - apic = &apic_physflat; - } - } + if (apic == &apic_flat && num_possible_cpus() > 8) + apic = &apic_physflat; printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 9ee87cfe0859..c7ee9c9e0245 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -595,9 +595,11 @@ void __init uv_system_init(void) for (j = 0; j < 64; j++) { if (!test_bit(j, &present)) continue; - uv_blade_info[blade].pnode = (i * 64 + j); + pnode = (i * 64 + j); + uv_blade_info[blade].pnode = pnode; uv_blade_info[blade].nr_possible_cpus = 0; uv_blade_info[blade].nr_online_cpus = 0; + max_pnode = max(pnode, max_pnode); blade++; } } @@ -635,10 +637,6 @@ void __init uv_system_init(void) uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid); uv_node_to_blade[nid] = blade; uv_cpu_to_blade[cpu] = blade; - max_pnode = max(pnode, max_pnode); - - printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n", - cpu, apicid, pnode, nid, lcpu, blade); } /* Add blade/pnode info for nodes without cpus */ @@ -650,7 +648,6 @@ void __init uv_system_init(void) pnode = (paddr >> m_val) & pnode_mask; blade = boot_pnode_to_blade(pnode); uv_node_to_blade[nid] = blade; - max_pnode = max(pnode, max_pnode); } map_gru_high(max_pnode); diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index c910a716a71c..3940fee7ea9f 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int apicid) /* * Fixup core topology information for AMD multi-node processors. - * Assumption 1: Number of cores in each internal node is the same. - * Assumption 2: Mixed systems with both single-node and dual-node - * processors are not supported. + * Assumption: Number of cores in each internal node is the same. */ #ifdef CONFIG_X86_HT static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c) { -#ifdef CONFIG_PCI - u32 t, cpn; - u8 n, n_id; + unsigned long long value; + u32 nodes, cores_per_node; int cpu = smp_processor_id(); + if (!cpu_has(c, X86_FEATURE_NODEID_MSR)) + return; + /* fixup topology information only once for a core */ if (cpu_has(c, X86_FEATURE_AMD_DCM)) return; - /* check for multi-node processor on boot cpu */ - t = read_pci_config(0, 24, 3, 0xe8); - if (!(t & (1 << 29))) + rdmsrl(MSR_FAM10H_NODE_ID, value); + + nodes = ((value >> 3) & 7) + 1; + if (nodes == 1) return; set_cpu_cap(c, X86_FEATURE_AMD_DCM); + cores_per_node = c->x86_max_cores / nodes; - /* cores per node: each internal node has half the number of cores */ - cpn = c->x86_max_cores >> 1; + /* store NodeID, use llc_shared_map to store sibling info */ + per_cpu(cpu_llc_id, cpu) = value & 7; - /* even-numbered NB_id of this dual-node processor */ - n = c->phys_proc_id << 1; - - /* - * determine internal node id and assign cores fifty-fifty to - * each node of the dual-node processor - */ - t = read_pci_config(0, 24 + n, 3, 0xe8); - n = (t>>30) & 0x3; - if (n == 0) { - if (c->cpu_core_id < cpn) - n_id = 0; - else - n_id = 1; - } else { - if (c->cpu_core_id < cpn) - n_id = 1; - else - n_id = 0; - } - - /* compute entire NodeID, use llc_shared_map to store sibling info */ - per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id; - - /* fixup core id to be in range from 0 to cpn */ - c->cpu_core_id = c->cpu_core_id % cpn; -#endif + /* fixup core id to be in range from 0 to (cores_per_node - 1) */ + c->cpu_core_id = c->cpu_core_id % cores_per_node; } #endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index cc25c2b4a567..4e34d10b841f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -540,7 +540,7 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c) } } -static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) +void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) { u32 tfms, xlvl; u32 ebx; @@ -579,6 +579,7 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) if (c->extended_cpuid_level >= 0x80000007) c->x86_power = cpuid_edx(0x80000007); + init_scattered_cpuid_features(c); } static void __cpuinit identify_cpu_without_cpuid(struct cpuinfo_x86 *c) @@ -727,7 +728,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c) get_model_name(c); /* Default name */ - init_scattered_cpuid_features(c); detect_nopl(c); } diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 6de9a908e400..eb19c0800044 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -33,5 +33,6 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[], *const __x86_cpu_dev_end[]; extern void display_cacheinfo(struct cpuinfo_x86 *c); +extern void get_cpu_cap(struct cpuinfo_x86 *c); #endif diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 8b581d3905cb..acb0115f43dc 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -741,6 +741,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) per_cpu(drv_data, policy->cpu) = NULL; acpi_processor_unregister_performance(data->acpi_data, policy->cpu); + kfree(data->freq_table); kfree(data); } diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index ab1cd30340f5..5e92606c4cf8 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -929,7 +929,8 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, powernow_table[i].index = index; /* Frequency may be rounded for these */ - if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) { + if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) + || boot_cpu_data.x86 == 0x11) { powernow_table[i].frequency = freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7); } else diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index a2a03cf4a489..6a77ccaed1aa 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -40,6 +40,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); c->cpuid_level = cpuid_eax(0); + get_cpu_cap(c); } } @@ -47,6 +48,27 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); + /* + * Atom erratum AAE44/AAF40/AAG38/AAH41: + * + * A race condition between speculative fetches and invalidating + * a large page. This is worked around in microcode, but we + * need the microcode to have already been loaded... so if it is + * not, recommend a BIOS update and disable large pages. + */ + if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2) { + u32 ucode, junk; + + wrmsr(MSR_IA32_UCODE_REV, 0, 0); + sync_core(); + rdmsr(MSR_IA32_UCODE_REV, junk, ucode); + + if (ucode < 0x20e) { + printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n"); + clear_cpu_cap(c, X86_FEATURE_PSE); + } + } + #ifdef CONFIG_X86_64 set_cpu_cap(c, X86_FEATURE_SYSENTER32); #else @@ -70,7 +92,8 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) if (c->x86_power & (1 << 8)) { set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); - sched_clock_stable = 1; + if (!check_tsc_unstable()) + sched_clock_stable = 1; } /* diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 8178d0352935..417990f04b5d 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -18,6 +18,7 @@ #include #include #include +#include #define LVL_1_INST 1 #define LVL_1_DATA 2 @@ -150,7 +151,8 @@ struct _cpuid4_info { union _cpuid4_leaf_ebx ebx; union _cpuid4_leaf_ecx ecx; unsigned long size; - unsigned long can_disable; + bool can_disable; + unsigned int l3_indices; DECLARE_BITMAP(shared_cpu_map, NR_CPUS); }; @@ -160,7 +162,8 @@ struct _cpuid4_info_regs { union _cpuid4_leaf_ebx ebx; union _cpuid4_leaf_ecx ecx; unsigned long size; - unsigned long can_disable; + bool can_disable; + unsigned int l3_indices; }; unsigned short num_cache_leaves; @@ -290,6 +293,36 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, (ebx->split.ways_of_associativity + 1) - 1; } +struct _cache_attr { + struct attribute attr; + ssize_t (*show)(struct _cpuid4_info *, char *); + ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count); +}; + +#ifdef CONFIG_CPU_SUP_AMD +static unsigned int __cpuinit amd_calc_l3_indices(void) +{ + /* + * We're called over smp_call_function_single() and therefore + * are on the correct cpu. + */ + int cpu = smp_processor_id(); + int node = cpu_to_node(cpu); + struct pci_dev *dev = node_to_k8_nb_misc(node); + unsigned int sc0, sc1, sc2, sc3; + u32 val = 0; + + pci_read_config_dword(dev, 0x1C4, &val); + + /* calculate subcache sizes */ + sc0 = !(val & BIT(0)); + sc1 = !(val & BIT(4)); + sc2 = !(val & BIT(8)) + !(val & BIT(9)); + sc3 = !(val & BIT(12)) + !(val & BIT(13)); + + return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1; +} + static void __cpuinit amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) { @@ -299,13 +332,108 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) if (boot_cpu_data.x86 == 0x11) return; - /* see erratum #382 */ - if ((boot_cpu_data.x86 == 0x10) && (boot_cpu_data.x86_model < 0x8)) + /* see errata #382 and #388 */ + if ((boot_cpu_data.x86 == 0x10) && + ((boot_cpu_data.x86_model < 0x8) || + (boot_cpu_data.x86_mask < 0x1))) return; - this_leaf->can_disable = 1; + /* not in virtualized environments */ + if (num_k8_northbridges == 0) + return; + + this_leaf->can_disable = true; + this_leaf->l3_indices = amd_calc_l3_indices(); } +static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, + unsigned int index) +{ + int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); + int node = amd_get_nb_id(cpu); + struct pci_dev *dev = node_to_k8_nb_misc(node); + unsigned int reg = 0; + + if (!this_leaf->can_disable) + return -EINVAL; + + if (!dev) + return -EINVAL; + + pci_read_config_dword(dev, 0x1BC + index * 4, ®); + return sprintf(buf, "0x%08x\n", reg); +} + +#define SHOW_CACHE_DISABLE(index) \ +static ssize_t \ +show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ +{ \ + return show_cache_disable(this_leaf, buf, index); \ +} +SHOW_CACHE_DISABLE(0) +SHOW_CACHE_DISABLE(1) + +static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, + const char *buf, size_t count, unsigned int index) +{ + int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); + int node = amd_get_nb_id(cpu); + struct pci_dev *dev = node_to_k8_nb_misc(node); + unsigned long val = 0; + +#define SUBCACHE_MASK (3UL << 20) +#define SUBCACHE_INDEX 0xfff + + if (!this_leaf->can_disable) + return -EINVAL; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (!dev) + return -EINVAL; + + if (strict_strtoul(buf, 10, &val) < 0) + return -EINVAL; + + /* do not allow writes outside of allowed bits */ + if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) || + ((val & SUBCACHE_INDEX) > this_leaf->l3_indices)) + return -EINVAL; + + val |= BIT(30); + pci_write_config_dword(dev, 0x1BC + index * 4, val); + /* + * We need to WBINVD on a core on the node containing the L3 cache which + * indices we disable therefore a simple wbinvd() is not sufficient. + */ + wbinvd_on_cpu(cpu); + pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31)); + return count; +} + +#define STORE_CACHE_DISABLE(index) \ +static ssize_t \ +store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ + const char *buf, size_t count) \ +{ \ + return store_cache_disable(this_leaf, buf, count, index); \ +} +STORE_CACHE_DISABLE(0) +STORE_CACHE_DISABLE(1) + +static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644, + show_cache_disable_0, store_cache_disable_0); +static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, + show_cache_disable_1, store_cache_disable_1); + +#else /* CONFIG_CPU_SUP_AMD */ +static void __cpuinit +amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) +{ +}; +#endif /* CONFIG_CPU_SUP_AMD */ + static int __cpuinit cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) @@ -523,18 +651,19 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) { struct _cpuid4_info *this_leaf, *sibling_leaf; unsigned long num_threads_sharing; - int index_msb, i; + int index_msb, i, sibling; struct cpuinfo_x86 *c = &cpu_data(cpu); if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) { - struct cpuinfo_x86 *d; - for_each_online_cpu(i) { + for_each_cpu(i, c->llc_shared_map) { if (!per_cpu(cpuid4_info, i)) continue; - d = &cpu_data(i); this_leaf = CPUID4_INFO_IDX(i, index); - cpumask_copy(to_cpumask(this_leaf->shared_cpu_map), - d->llc_shared_map); + for_each_cpu(sibling, c->llc_shared_map) { + if (!cpu_online(sibling)) + continue; + set_bit(sibling, this_leaf->shared_cpu_map); + } } return; } @@ -726,82 +855,6 @@ static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) #define to_object(k) container_of(k, struct _index_kobject, kobj) #define to_attr(a) container_of(a, struct _cache_attr, attr) -static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, - unsigned int index) -{ - int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); - int node = cpu_to_node(cpu); - struct pci_dev *dev = node_to_k8_nb_misc(node); - unsigned int reg = 0; - - if (!this_leaf->can_disable) - return -EINVAL; - - if (!dev) - return -EINVAL; - - pci_read_config_dword(dev, 0x1BC + index * 4, ®); - return sprintf(buf, "%x\n", reg); -} - -#define SHOW_CACHE_DISABLE(index) \ -static ssize_t \ -show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ -{ \ - return show_cache_disable(this_leaf, buf, index); \ -} -SHOW_CACHE_DISABLE(0) -SHOW_CACHE_DISABLE(1) - -static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, - const char *buf, size_t count, unsigned int index) -{ - int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); - int node = cpu_to_node(cpu); - struct pci_dev *dev = node_to_k8_nb_misc(node); - unsigned long val = 0; - unsigned int scrubber = 0; - - if (!this_leaf->can_disable) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!dev) - return -EINVAL; - - if (strict_strtoul(buf, 10, &val) < 0) - return -EINVAL; - - val |= 0xc0000000; - - pci_read_config_dword(dev, 0x58, &scrubber); - scrubber &= ~0x1f000000; - pci_write_config_dword(dev, 0x58, scrubber); - - pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000); - wbinvd(); - pci_write_config_dword(dev, 0x1BC + index * 4, val); - return count; -} - -#define STORE_CACHE_DISABLE(index) \ -static ssize_t \ -store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ - const char *buf, size_t count) \ -{ \ - return store_cache_disable(this_leaf, buf, count, index); \ -} -STORE_CACHE_DISABLE(0) -STORE_CACHE_DISABLE(1) - -struct _cache_attr { - struct attribute attr; - ssize_t (*show)(struct _cpuid4_info *, char *); - ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count); -}; - #define define_one_ro(_name) \ static struct _cache_attr _name = \ __ATTR(_name, 0444, show_##_name, NULL) @@ -816,23 +869,28 @@ define_one_ro(size); define_one_ro(shared_cpu_map); define_one_ro(shared_cpu_list); -static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644, - show_cache_disable_0, store_cache_disable_0); -static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, - show_cache_disable_1, store_cache_disable_1); +#define DEFAULT_SYSFS_CACHE_ATTRS \ + &type.attr, \ + &level.attr, \ + &coherency_line_size.attr, \ + &physical_line_partition.attr, \ + &ways_of_associativity.attr, \ + &number_of_sets.attr, \ + &size.attr, \ + &shared_cpu_map.attr, \ + &shared_cpu_list.attr static struct attribute *default_attrs[] = { - &type.attr, - &level.attr, - &coherency_line_size.attr, - &physical_line_partition.attr, - &ways_of_associativity.attr, - &number_of_sets.attr, - &size.attr, - &shared_cpu_map.attr, - &shared_cpu_list.attr, + DEFAULT_SYSFS_CACHE_ATTRS, + NULL +}; + +static struct attribute *default_l3_attrs[] = { + DEFAULT_SYSFS_CACHE_ATTRS, +#ifdef CONFIG_CPU_SUP_AMD &cache_disable_0.attr, &cache_disable_1.attr, +#endif NULL }; @@ -923,6 +981,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) unsigned int cpu = sys_dev->id; unsigned long i, j; struct _index_kobject *this_object; + struct _cpuid4_info *this_leaf; int retval; retval = cpuid4_cache_sysfs_init(cpu); @@ -941,6 +1000,14 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) this_object = INDEX_KOBJECT_PTR(cpu, i); this_object->cpu = cpu; this_object->index = i; + + this_leaf = CPUID4_INFO_IDX(cpu, i); + + if (this_leaf->can_disable) + ktype_cache.default_attrs = default_l3_attrs; + else + ktype_cache.default_attrs = default_attrs; + retval = kobject_init_and_add(&(this_object->kobj), &ktype_cache, per_cpu(cache_kobject, cpu), diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 83a3d1f4efca..8387792a696b 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -140,6 +140,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) address = (low & MASK_BLKPTR_LO) >> 21; if (!address) break; + address += MCG_XBLK_ADDR; } else ++address; @@ -147,12 +148,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) if (rdmsr_safe(address, &low, &high)) break; - if (!(high & MASK_VALID_HI)) { - if (block) - continue; - else - break; - } + if (!(high & MASK_VALID_HI)) + continue; if (!(high & MASK_CNTP_HI) || (high & MASK_LOCKED_HI)) diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 73c86db5acbe..650c6a5bdae6 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -948,7 +948,7 @@ int __init amd_special_default_mtrr(void) if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) return 0; - if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) + if (boot_cpu_data.x86 < 0xf) return 0; /* In case some hypervisor doesn't pass SYSCFG through: */ if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b5801c311846..0ff02cae710b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -190,6 +190,97 @@ static u64 __read_mostly hw_cache_event_ids [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX]; +static const u64 westmere_hw_cache_event_ids + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = +{ + [ C(L1D) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */ + [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */ + [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */ + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */ + [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */ + }, + }, + [ C(L1I ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */ + [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0, + }, + }, + [ C(LL ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS */ + [ C(RESULT_MISS) ] = 0x0224, /* L2_RQSTS.LD_MISS */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS */ + [ C(RESULT_MISS) ] = 0x0824, /* L2_RQSTS.RFO_MISS */ + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference */ + [ C(RESULT_MISS) ] = 0x412e, /* LLC Misses */ + }, + }, + [ C(DTLB) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */ + [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */ + [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */ + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0, + }, + }, + [ C(ITLB) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */ + [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.ANY */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + }, + [ C(BPU ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */ + [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + }, +}; + static const u64 nehalem_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] @@ -914,8 +1005,11 @@ static int __hw_perf_event_init(struct perf_event *event) if (atomic_read(&active_events) == 0) { if (!reserve_pmc_hardware()) err = -EBUSY; - else + else { err = reserve_bts_hardware(); + if (err) + release_pmc_hardware(); + } } if (!err) atomic_inc(&active_events); @@ -1999,6 +2093,7 @@ static int intel_pmu_init(void) * Install the hw-cache-events table: */ switch (boot_cpu_data.x86_model) { + case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */ @@ -2009,7 +2104,9 @@ static int intel_pmu_init(void) pr_cont("Core2 events, "); break; default: - case 26: + case 26: /* 45 nm nehalem, "Bloomfield" */ + case 30: /* 45 nm nehalem, "Lynnfield" */ + case 46: /* 45 nm nehalem-ex, "Beckton" */ memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -2021,6 +2118,14 @@ static int intel_pmu_init(void) pr_cont("Atom events, "); break; + + case 37: /* 32 nm nehalem, "Clarkdale" */ + case 44: /* 32 nm nehalem, "Gulftown" */ + memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids, + sizeof(hw_cache_event_ids)); + + pr_cont("Westmere events, "); + break; } return 0; } diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 1cbed97b59cf..9580152f5813 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -50,7 +51,7 @@ static inline int __vmware_platform(void) static unsigned long vmware_get_tsc_khz(void) { - uint64_t tsc_hz; + uint64_t tsc_hz, lpj; uint32_t eax, ebx, ecx, edx; VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); @@ -61,6 +62,13 @@ static unsigned long vmware_get_tsc_khz(void) printk(KERN_INFO "TSC freq read from hypervisor : %lu.%03lu MHz\n", (unsigned long) tsc_hz / 1000, (unsigned long) tsc_hz % 1000); + + if (!preset_lpj) { + lpj = ((u64)tsc_hz * 1000); + do_div(lpj, HZ); + preset_lpj = lpj; + } + return tsc_hz; } diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 5e409dc298a4..ff958248e61d 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -27,7 +27,6 @@ #include #include #include -#include #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) @@ -104,10 +103,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs) #ifdef CONFIG_HPET_TIMER hpet_disable(); #endif - -#ifdef CONFIG_X86_64 - pci_iommu_shutdown(); -#endif - crash_save_cpu(regs, safe_smp_processor_id()); } diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index 045b36cada65..994828899e09 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -34,7 +34,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!csize) return 0; - vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); + vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE); if (!vaddr) return -ENOMEM; @@ -46,6 +46,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, } else memcpy(buf, vaddr + offset, csize); + set_iounmap_nonlazy(); iounmap(vaddr); return csize; } diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 050c278481b1..34c3308730f8 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -324,7 +324,7 @@ ENTRY(startup_32_smp) /* * Enable paging */ - movl $pa(swapper_pg_dir),%eax + movl pa(initial_page_table), %eax movl %eax,%cr3 /* set the page table pointer.. */ movl %cr0,%eax orl $X86_CR0_PG,%eax @@ -604,6 +604,8 @@ ignore_int: .align 4 ENTRY(initial_code) .long i386_start_kernel +ENTRY(initial_page_table) + .long pa(swapper_pg_dir) /* * BSS section @@ -619,6 +621,10 @@ ENTRY(swapper_pg_dir) #endif swapper_pg_fixmap: .fill 1024,4,0 +#ifdef CONFIG_X86_TRAMPOLINE +ENTRY(trampoline_pg_dir) + .fill 1024,4,0 +#endif ENTRY(empty_zero_page) .fill 4096,1,0 diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 58778736496a..c771e1a37b9d 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -385,11 +385,28 @@ static int hpet_next_event(unsigned long delta, hpet_writel(cnt, HPET_Tn_CMP(timer)); /* - * We need to read back the CMP register to make sure that - * what we wrote hit the chip before we compare it to the - * counter. + * We need to read back the CMP register on certain HPET + * implementations (ATI chipsets) which seem to delay the + * transfer of the compare register into the internal compare + * logic. With small deltas this might actually be too late as + * the counter could already be higher than the compare value + * at that point and we would wait for the next hpet interrupt + * forever. We found out that reading the CMP register back + * forces the transfer so we can rely on the comparison with + * the counter register below. If the read back from the + * compare register does not match the value we programmed + * then we might have a real hardware problem. We can not do + * much about it here, but at least alert the user/admin with + * a prominent warning. + * An erratum on some chipsets (ICH9,..), results in comparator read + * immediately following a write returning old value. Workaround + * for this is to read this value second time, when first + * read returns old value. */ - WARN_ON_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt); + if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) { + WARN_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt, + KERN_WARNING "hpet: compare register read back failed.\n"); + } return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; } @@ -480,7 +497,7 @@ static int hpet_assign_irq(struct hpet_dev *dev) { unsigned int irq; - irq = create_irq(); + irq = create_irq_nr(0, -1); if (!irq) return -EINVAL; @@ -932,7 +949,7 @@ fs_initcall(hpet_late_init); void hpet_disable(void) { - if (is_hpet_capable()) { + if (is_hpet_capable() && hpet_virt_address) { unsigned long cfg = hpet_readl(HPET_CFG); if (hpet_legacy_int_enabled) { diff --git a/arch/x86/kernel/k8.c b/arch/x86/kernel/k8.c index cbc4332a77b2..9b895464dd03 100644 --- a/arch/x86/kernel/k8.c +++ b/arch/x86/kernel/k8.c @@ -121,3 +121,17 @@ void k8_flush_garts(void) } EXPORT_SYMBOL_GPL(k8_flush_garts); +static __init int init_k8_nbs(void) +{ + int err = 0; + + err = cache_k8_northbridges(); + + if (err < 0) + printk(KERN_NOTICE "K8 NB: Cannot enumerate AMD northbridges.\n"); + + return err; +} + +/* This has to go after the PCI subsystem */ +fs_initcall(init_k8_nbs); diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 5be95ef4ffec..e07bc4ef2829 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -359,13 +359,6 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) x86_init.mpparse.mpc_record(1); } -#ifdef CONFIG_X86_BIGSMP - generic_bigsmp_probe(); -#endif - - if (apic->setup_apic_routing) - apic->setup_apic_routing(); - if (!num_processors) printk(KERN_ERR "MPTABLE: no processors registered!\n"); return num_processors; diff --git a/arch/x86/kernel/olpc.c b/arch/x86/kernel/olpc.c index 4006c522adc7..38faf7211d0b 100644 --- a/arch/x86/kernel/olpc.c +++ b/arch/x86/kernel/olpc.c @@ -115,6 +115,7 @@ int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, unsigned long flags; int ret = -EIO; int i; + int restarts = 0; spin_lock_irqsave(&ec_lock, flags); @@ -171,7 +172,9 @@ int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, if (wait_on_obf(0x6c, 1)) { printk(KERN_ERR "olpc-ec: timeout waiting for" " EC to provide data!\n"); - goto restart; + if (restarts++ < 10) + goto restart; + goto err; } outbuf[i] = inb(0x68); printk(KERN_DEBUG "olpc-ec: received 0x%x\n", diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index e6ec8a2df1c3..1a2d4b19eb23 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -102,11 +102,16 @@ int use_calgary __read_mostly = 0; #define PMR_SOFTSTOPFAULT 0x40000000 #define PMR_HARDSTOP 0x20000000 -#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ -#define MAX_NUM_CHASSIS 8 /* max number of chassis */ -/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */ -#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) -#define PHBS_PER_CALGARY 4 +/* + * The maximum PHB bus number. + * x3950M2 (rare): 8 chassis, 48 PHBs per chassis = 384 + * x3950M2: 4 chassis, 48 PHBs per chassis = 192 + * x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 + * x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 + */ +#define MAX_PHB_BUS_NUM 256 + +#define PHBS_PER_CALGARY 4 /* register offsets in Calgary's internal register space */ static const unsigned long tar_offsets[] = { @@ -1053,8 +1058,6 @@ static int __init calgary_init_one(struct pci_dev *dev) struct iommu_table *tbl; int ret; - BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); - bbar = busno_to_bbar(dev->bus->number); ret = calgary_setup_tar(dev, bbar); if (ret) diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index fcc0b5c022c1..1c766915094e 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -553,6 +553,9 @@ static void enable_gart_translations(void) enable_gart_translation(dev, __pa(agp_gatt_table)); } + + /* Flush the GART-TLB to remove stale entries */ + k8_flush_garts(); } /* @@ -717,7 +720,7 @@ void __init gart_iommu_init(void) unsigned long scratch; long i; - if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) + if (num_k8_northbridges == 0) return; #ifndef CONFIG_AGP_AMD64 diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f010ab424f1f..5fd5b07bf3a5 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -439,21 +439,39 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) } /* - * Check for AMD CPUs, which have potentially C1E support + * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e. + * For more information see + * - Erratum #400 for NPT family 0xf and family 0x10 CPUs + * - Erratum #365 for family 0x11 (not affected because C1e not in use) */ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) { + u64 val; if (c->x86_vendor != X86_VENDOR_AMD) - return 0; - - if (c->x86 < 0x0F) - return 0; + goto no_c1e_idle; /* Family 0x0f models < rev F do not have C1E */ - if (c->x86 == 0x0f && c->x86_model < 0x40) - return 0; + if (c->x86 == 0x0F && c->x86_model >= 0x40) + return 1; - return 1; + if (c->x86 == 0x10) { + /* + * check OSVW bit for CPUs that are not affected + * by erratum #400 + */ + if (cpu_has(c, X86_FEATURE_OSVW)) { + rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val); + if (val >= 2) { + rdmsrl(MSR_AMD64_OSVW_STATUS, val); + if (!(val & BIT(1))) + goto no_c1e_idle; + } + } + return 1; + } + +no_c1e_idle: + return 0; } static cpumask_var_t c1e_mask; diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index f9ce04f61003..868fdb407bb9 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -295,11 +295,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, set_tsk_thread_flag(p, TIF_FORK); - p->thread.fs = me->thread.fs; - p->thread.gs = me->thread.gs; - savesegment(gs, p->thread.gsindex); + p->thread.gs = p->thread.gsindex ? 0 : me->thread.gs; savesegment(fs, p->thread.fsindex); + p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs; savesegment(es, p->thread.es); savesegment(ds, p->thread.ds); @@ -546,6 +545,7 @@ void set_personality_ia32(void) /* Make sure to be in 32bit mode */ set_thread_flag(TIF_IA32); + current->personality |= force_personality32; /* Prepare the first "return" to user space */ current_thread_info()->status |= TS_COMPAT; diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 03801f2f761f..dfdfe4662e05 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -109,11 +109,14 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) return pv_tsc_khz; } +static atomic64_t last_value = ATOMIC64_INIT(0); + cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) { struct pvclock_shadow_time shadow; unsigned version; cycle_t ret, offset; + u64 last; do { version = pvclock_get_time_values(&shadow, src); @@ -123,6 +126,27 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) barrier(); } while (version != src->version); + /* + * Assumption here is that last_value, a global accumulator, always goes + * forward. If we are less than that, we should not be much smaller. + * We assume there is an error marging we're inside, and then the correction + * does not sacrifice accuracy. + * + * For reads: global may have changed between test and return, + * but this means someone else updated poked the clock at a later time. + * We just need to make sure we are not seeing a backwards event. + * + * For updates: last_value = ret is not enough, since two vcpus could be + * updating at the same time, and one of them could be slightly behind, + * making the assumption that last_value always go forward fail to hold. + */ + last = atomic64_read(&last_value); + do { + if (ret < last) + return last; + last = atomic64_cmpxchg(&last_value, last, ret); + } while (unlikely(last != ret)); + return ret; } diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 0040164f1a82..12e9feaa2f7a 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -512,6 +512,7 @@ static void __init quirk_amd_nb_node(struct pci_dev *dev) { struct pci_dev *nb_ht; unsigned int devfn; + u32 node; u32 val; devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0); @@ -520,7 +521,13 @@ static void __init quirk_amd_nb_node(struct pci_dev *dev) return; pci_read_config_dword(nb_ht, 0x60, &val); - set_dev_node(&dev->dev, val & 7); + node = val & 7; + /* + * Some hardware may return an invalid node ID, + * so check it first: + */ + if (node_online(node)) + set_dev_node(&dev->dev, node); pci_dev_put(nb_ht); } diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index bff34d68d9d1..200fcde41aa2 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -461,6 +461,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"), }, }, + { /* Handle problems with rebooting on the iMac9,1. */ + .callback = set_pci_reboot, + .ident = "Apple iMac9,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), + }, + }, { } }; @@ -625,7 +633,7 @@ void native_machine_shutdown(void) /* O.K Now that I'm on the appropriate processor, * stop all of the others. */ - smp_send_stop(); + stop_other_cpus(); #endif lapic_shutdown(); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 8425f7ebe89e..5449a2698242 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -110,6 +110,7 @@ #include #endif #include +#include /* * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. @@ -688,6 +689,17 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "DG45FC"), }, }, + /* + * The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so + * match on the product name. + */ + { + .callback = dmi_low_memory_corruption, + .ident = "Phoenix BIOS", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), + }, + }, #endif {} }; @@ -987,6 +999,8 @@ void __init setup_arch(char **cmdline_p) paging_init(); x86_init.paging.pagetable_setup_done(swapper_pg_dir); + setup_trampoline_page_table(); + tboot_probe(); #ifdef CONFIG_X86_64 diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index ec1de97600e7..29f0a78ec887 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -158,10 +158,10 @@ asmlinkage void smp_reboot_interrupt(void) irq_exit(); } -static void native_smp_send_stop(void) +static void native_stop_other_cpus(int wait) { unsigned long flags; - unsigned long wait; + unsigned long timeout; if (reboot_force) return; @@ -178,9 +178,12 @@ static void native_smp_send_stop(void) if (num_online_cpus() > 1) { apic->send_IPI_allbutself(REBOOT_VECTOR); - /* Don't wait longer than a second */ - wait = USEC_PER_SEC; - while (num_online_cpus() > 1 && wait--) + /* + * Don't wait longer than a second if the caller + * didn't ask us to wait. + */ + timeout = USEC_PER_SEC; + while (num_online_cpus() > 1 && (wait || timeout--)) udelay(1); } @@ -226,7 +229,7 @@ struct smp_ops smp_ops = { .smp_prepare_cpus = native_smp_prepare_cpus, .smp_cpus_done = native_smp_cpus_done, - .smp_send_stop = native_smp_send_stop, + .stop_other_cpus = native_stop_other_cpus, .smp_send_reschedule = native_smp_send_reschedule, .cpu_up = native_cpu_up, diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 565ebc65920e..7e8e905e2ccb 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -70,7 +70,6 @@ #ifdef CONFIG_X86_32 u8 apicid_2_node[MAX_APICID]; -static int low_mappings; #endif /* State of each CPU */ @@ -88,6 +87,25 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 }; static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); #define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) #define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) + +/* + * We need this for trampoline_base protection from concurrent accesses when + * off- and onlining cores wildly. + */ +static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex); + +void cpu_hotplug_driver_lock() +{ + mutex_lock(&x86_cpu_hotplug_driver_mutex); +} + +void cpu_hotplug_driver_unlock() +{ + mutex_unlock(&x86_cpu_hotplug_driver_mutex); +} + +ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; } +ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; } #else static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; #define get_idle_for_cpu(x) (idle_thread_array[(x)]) @@ -273,6 +291,18 @@ notrace static void __cpuinit start_secondary(void *unused) * fragile that we want to limit the things done here to the * most necessary things. */ + +#ifdef CONFIG_X86_32 + /* + * Switch away from the trampoline page-table + * + * Do this before cpu_init() because it needs to access per-cpu + * data which may not be mapped in the trampoline page-table. + */ + load_cr3(swapper_pg_dir); + __flush_tlb_all(); +#endif + vmi_bringup(); cpu_init(); preempt_disable(); @@ -291,12 +321,6 @@ notrace static void __cpuinit start_secondary(void *unused) enable_8259A_irq(0); } -#ifdef CONFIG_X86_32 - while (low_mappings) - cpu_relax(); - __flush_tlb_all(); -#endif - /* This must be done before setting cpu_online_mask */ set_cpu_sibling_map(raw_smp_processor_id()); wmb(); @@ -722,6 +746,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) #ifdef CONFIG_X86_32 /* Stack for startup_32 can be just as for start_secondary onwards */ irq_ctx_init(cpu); + initial_page_table = __pa(&trampoline_pg_dir); #else clear_tsk_thread_flag(c_idle.idle, TIF_FORK); initial_gs = per_cpu_offset(cpu); @@ -866,20 +891,8 @@ int __cpuinit native_cpu_up(unsigned int cpu) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; -#ifdef CONFIG_X86_32 - /* init low mem mapping */ - clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, - min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); - flush_tlb_all(); - low_mappings = 1; - err = do_boot_cpu(apicid, cpu); - zap_low_mappings(false); - low_mappings = 0; -#else - err = do_boot_cpu(apicid, cpu); -#endif if (err) { pr_debug("do_boot_cpu failed %d\n", err); return -EIO; @@ -1066,9 +1079,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) set_cpu_sibling_map(0); enable_IR_x2apic(); -#ifdef CONFIG_X86_64 default_setup_apic_routing(); -#endif if (smp_sanity_check(max_cpus) < 0) { printk(KERN_INFO "SMP disabled\n"); diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 86c9f91b48ae..46b827778d16 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -46,6 +46,7 @@ /* Global pointer to shared data; NULL means no measured launch. */ struct tboot *tboot __read_mostly; +EXPORT_SYMBOL(tboot); /* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */ #define AP_WAIT_TIMEOUT 1 diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c index cd022121cab6..0ac23a7bf6f1 100644 --- a/arch/x86/kernel/trampoline.c +++ b/arch/x86/kernel/trampoline.c @@ -1,6 +1,7 @@ #include #include +#include #include #if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP) @@ -39,3 +40,19 @@ unsigned long __trampinit setup_trampoline(void) memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE); return virt_to_phys(trampoline_base); } + +void __init setup_trampoline_page_table(void) +{ +#ifdef CONFIG_X86_32 + /* Copy kernel address range */ + clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY, + swapper_pg_dir + KERNEL_PGD_BOUNDARY, + KERNEL_PGD_PTRS); + + /* Initialize low mappings */ + clone_pgd_range(trampoline_pg_dir, + swapper_pg_dir + KERNEL_PGD_BOUNDARY, + min_t(unsigned long, KERNEL_PGD_PTRS, + KERNEL_PGD_BOUNDARY)); +#endif +} diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 597683aa5ba0..aaefa71888cb 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -626,6 +626,44 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) local_irq_restore(flags); } +static unsigned long long cyc2ns_suspend; + +void save_sched_clock_state(void) +{ + if (!sched_clock_stable) + return; + + cyc2ns_suspend = sched_clock(); +} + +/* + * Even on processors with invariant TSC, TSC gets reset in some the + * ACPI system sleep states. And in some systems BIOS seem to reinit TSC to + * arbitrary value (still sync'd across cpu's) during resume from such sleep + * states. To cope up with this, recompute the cyc2ns_offset for each cpu so + * that sched_clock() continues from the point where it was left off during + * suspend. + */ +void restore_sched_clock_state(void) +{ + unsigned long long offset; + unsigned long flags; + int cpu; + + if (!sched_clock_stable) + return; + + local_irq_save(flags); + + __get_cpu_var(cyc2ns_offset) = 0; + offset = cyc2ns_suspend - sched_clock(); + + for_each_possible_cpu(cpu) + per_cpu(cyc2ns_offset, cpu) = offset; + + local_irq_restore(flags); +} + #ifdef CONFIG_CPU_FREQ /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 8cb4974ff599..62f39d79b775 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -73,7 +73,8 @@ void update_vsyscall_tz(void) write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); } -void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) +void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, + u32 mult) { unsigned long flags; @@ -82,7 +83,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) vsyscall_gtod_data.clock.vread = clock->vread; vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; vsyscall_gtod_data.clock.mask = clock->mask; - vsyscall_gtod_data.clock.mult = clock->mult; + vsyscall_gtod_data.clock.mult = mult; vsyscall_gtod_data.clock.shift = clock->shift; vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e02dbb670d5b..1350e43cc02f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -75,6 +75,7 @@ #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ #define GroupMask 0xff /* Group number stored in bits 0:7 */ +#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */ /* Source 2 operand type */ #define Src2None (0<<29) #define Src2CL (1<<29) @@ -86,6 +87,7 @@ enum { Group1_80, Group1_81, Group1_82, Group1_83, Group1A, Group3_Byte, Group3, Group4, Group5, Group7, + Group8, Group9, }; static u32 opcode_table[256] = { @@ -203,7 +205,7 @@ static u32 opcode_table[256] = { SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* 0xF0 - 0xF7 */ 0, 0, 0, 0, - ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, + ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3, /* 0xF8 - 0xFF */ ImplicitOps, 0, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, @@ -211,16 +213,20 @@ static u32 opcode_table[256] = { static u32 twobyte_table[256] = { /* 0x00 - 0x0F */ - 0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0, - ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, + 0, Group | GroupDual | Group7, 0, 0, + 0, ImplicitOps, ImplicitOps | Priv, 0, + ImplicitOps | Priv, ImplicitOps | Priv, 0, 0, + 0, ImplicitOps | ModRM, 0, 0, /* 0x10 - 0x1F */ 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2F */ - ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, + ModRM | ImplicitOps | Priv, ModRM | Priv, + ModRM | ImplicitOps | Priv, ModRM | Priv, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3F */ - ImplicitOps, 0, ImplicitOps, 0, - ImplicitOps, ImplicitOps, 0, 0, + ImplicitOps | Priv, 0, ImplicitOps | Priv, 0, + ImplicitOps, ImplicitOps | Priv, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x47 */ DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, @@ -258,11 +264,12 @@ static u32 twobyte_table[256] = { 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem16 | ModRM | Mov, /* 0xB8 - 0xBF */ - 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, + 0, 0, Group | Group8, DstMem | SrcReg | ModRM | BitOp, 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem16 | ModRM | Mov, /* 0xC0 - 0xCF */ - 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM, + 0, 0, 0, DstMem | SrcReg | ModRM | Mov, + 0, 0, 0, Group | GroupDual | Group9, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -311,24 +318,39 @@ static u32 group_table[] = { SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, [Group7*8] = - 0, 0, ModRM | SrcMem, ModRM | SrcMem, + 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv, SrcNone | ModRM | DstMem | Mov, 0, - SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, + SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv, + [Group8*8] = + 0, 0, 0, 0, + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, + DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM, + [Group9*8] = + 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, }; static u32 group2_table[] = { [Group7*8] = - SrcNone | ModRM, 0, 0, SrcNone | ModRM, + SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM, SrcNone | ModRM | DstMem | Mov, 0, SrcMem16 | ModRM | Mov, 0, + [Group9*8] = + 0, 0, 0, 0, 0, 0, 0, 0, }; /* EFLAGS bit definitions. */ +#define EFLG_ID (1<<21) +#define EFLG_VIP (1<<20) +#define EFLG_VIF (1<<19) +#define EFLG_AC (1<<18) #define EFLG_VM (1<<17) #define EFLG_RF (1<<16) +#define EFLG_IOPL (3<<12) +#define EFLG_NT (1<<14) #define EFLG_OF (1<<11) #define EFLG_DF (1<<10) #define EFLG_IF (1<<9) +#define EFLG_TF (1<<8) #define EFLG_SF (1<<7) #define EFLG_ZF (1<<6) #define EFLG_AF (1<<4) @@ -597,7 +619,7 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, if (linear < fc->start || linear >= fc->end) { size = min(15UL, PAGE_SIZE - offset_in_page(linear)); - rc = ops->read_std(linear, fc->data, size, ctxt->vcpu); + rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL); if (rc) return rc; fc->start = linear; @@ -652,11 +674,11 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, op_bytes = 3; *address = 0; rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, - ctxt->vcpu); + ctxt->vcpu, NULL); if (rc) return rc; rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, - ctxt->vcpu); + ctxt->vcpu, NULL); return rc; } @@ -880,6 +902,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) switch (mode) { case X86EMUL_MODE_REAL: + case X86EMUL_MODE_VM86: case X86EMUL_MODE_PROT16: def_op_bytes = def_ad_bytes = 2; break; @@ -1189,6 +1212,49 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt, return rc; } +static int emulate_popf(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + void *dest, int len) +{ + int rc; + unsigned long val, change_mask; + int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; + int cpl = kvm_x86_ops->get_cpl(ctxt->vcpu); + + rc = emulate_pop(ctxt, ops, &val, len); + if (rc != X86EMUL_CONTINUE) + return rc; + + change_mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_OF + | EFLG_TF | EFLG_DF | EFLG_NT | EFLG_RF | EFLG_AC | EFLG_ID; + + switch(ctxt->mode) { + case X86EMUL_MODE_PROT64: + case X86EMUL_MODE_PROT32: + case X86EMUL_MODE_PROT16: + if (cpl == 0) + change_mask |= EFLG_IOPL; + if (cpl <= iopl) + change_mask |= EFLG_IF; + break; + case X86EMUL_MODE_VM86: + if (iopl < 3) { + kvm_inject_gp(ctxt->vcpu, 0); + return X86EMUL_PROPAGATE_FAULT; + } + change_mask |= EFLG_IF; + break; + default: /* real mode */ + change_mask |= (EFLG_IOPL | EFLG_IF); + break; + } + + *(unsigned long *)dest = + (ctxt->eflags & ~change_mask) | (val & change_mask); + + return rc; +} + static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -1330,7 +1396,7 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); if (rc) return rc; - rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS); + rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, VCPU_SREG_CS); return rc; } @@ -1438,7 +1504,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt) /* syscall is not available in real mode */ if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL - || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) + || ctxt->mode == X86EMUL_MODE_VM86) return -1; setup_syscalls_segments(ctxt, &cs, &ss); @@ -1490,9 +1556,8 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) if (c->lock_prefix) return -1; - /* inject #GP if in real mode or paging is disabled */ - if (ctxt->mode == X86EMUL_MODE_REAL || - !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { + /* inject #GP if in real mode */ + if (ctxt->mode == X86EMUL_MODE_REAL) { kvm_inject_gp(ctxt->vcpu, 0); return -1; } @@ -1556,15 +1621,9 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) if (c->lock_prefix) return -1; - /* inject #GP if in real mode or paging is disabled */ - if (ctxt->mode == X86EMUL_MODE_REAL - || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { - kvm_inject_gp(ctxt->vcpu, 0); - return -1; - } - - /* sysexit must be called from CPL 0 */ - if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) { + /* inject #GP if in real mode or Virtual 8086 mode */ + if (ctxt->mode == X86EMUL_MODE_REAL || + ctxt->mode == X86EMUL_MODE_VM86) { kvm_inject_gp(ctxt->vcpu, 0); return -1; } @@ -1611,6 +1670,57 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) return 0; } +static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) +{ + int iopl; + if (ctxt->mode == X86EMUL_MODE_REAL) + return false; + if (ctxt->mode == X86EMUL_MODE_VM86) + return true; + iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; + return kvm_x86_ops->get_cpl(ctxt->vcpu) > iopl; +} + +static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 port, u16 len) +{ + struct kvm_segment tr_seg; + int r; + u16 io_bitmap_ptr; + u8 perm, bit_idx = port & 0x7; + unsigned mask = (1 << len) - 1; + + kvm_get_segment(ctxt->vcpu, &tr_seg, VCPU_SREG_TR); + if (tr_seg.unusable) + return false; + if (tr_seg.limit < 103) + return false; + r = ops->read_std(tr_seg.base + 102, &io_bitmap_ptr, 2, ctxt->vcpu, + NULL); + if (r != X86EMUL_CONTINUE) + return false; + if (io_bitmap_ptr + port/8 > tr_seg.limit) + return false; + r = ops->read_std(tr_seg.base + io_bitmap_ptr + port/8, &perm, 1, + ctxt->vcpu, NULL); + if (r != X86EMUL_CONTINUE) + return false; + if ((perm >> bit_idx) & mask) + return false; + return true; +} + +static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + u16 port, u16 len) +{ + if (emulator_bad_iopl(ctxt)) + if (!emulator_io_port_access_allowed(ctxt, ops, port, len)) + return false; + return true; +} + int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -1632,6 +1742,12 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); saved_eip = c->eip; + /* Privileged instruction can be executed only in CPL=0 */ + if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) { + kvm_inject_gp(ctxt->vcpu, 0); + goto done; + } + if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) memop = c->modrm_ea; @@ -1764,7 +1880,12 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) break; case 0x6c: /* insb */ case 0x6d: /* insw/insd */ - if (kvm_emulate_pio_string(ctxt->vcpu, NULL, + if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], + (c->d & ByteOp) ? 1 : c->op_bytes)) { + kvm_inject_gp(ctxt->vcpu, 0); + goto done; + } + if (kvm_emulate_pio_string(ctxt->vcpu, NULL, 1, (c->d & ByteOp) ? 1 : c->op_bytes, c->rep_prefix ? @@ -1780,6 +1901,11 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) return 0; case 0x6e: /* outsb */ case 0x6f: /* outsw/outsd */ + if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], + (c->d & ByteOp) ? 1 : c->op_bytes)) { + kvm_inject_gp(ctxt->vcpu, 0); + goto done; + } if (kvm_emulate_pio_string(ctxt->vcpu, NULL, 0, (c->d & ByteOp) ? 1 : c->op_bytes, @@ -1866,25 +1992,19 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) break; case 0x8e: { /* mov seg, r/m16 */ uint16_t sel; - int type_bits; - int err; sel = c->src.val; + + if (c->modrm_reg == VCPU_SREG_CS || + c->modrm_reg > VCPU_SREG_GS) { + kvm_queue_exception(ctxt->vcpu, UD_VECTOR); + goto done; + } + if (c->modrm_reg == VCPU_SREG_SS) toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); - if (c->modrm_reg <= 5) { - type_bits = (c->modrm_reg == 1) ? 9 : 1; - err = kvm_load_segment_descriptor(ctxt->vcpu, sel, - type_bits, c->modrm_reg); - } else { - printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n", - c->modrm); - goto cannot_emulate; - } - - if (err < 0) - goto cannot_emulate; + rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg); c->dst.type = OP_NONE; /* Disable writeback. */ break; @@ -1913,7 +2033,10 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) c->dst.type = OP_REG; c->dst.ptr = (unsigned long *) &ctxt->eflags; c->dst.bytes = c->op_bytes; - goto pop_instruction; + rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xa0 ... 0xa1: /* mov */ c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; c->dst.val = c->src.val; @@ -2051,11 +2174,9 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) case 0xe9: /* jmp rel */ goto jmp; case 0xea: /* jmp far */ - if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9, - VCPU_SREG_CS) < 0) { - DPRINTF("jmp far: Failed to load CS descriptor\n"); - goto cannot_emulate; - } + if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, + VCPU_SREG_CS)) + goto done; c->eip = c->src.val; break; @@ -2073,7 +2194,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) case 0xef: /* out (e/r)ax,dx */ port = c->regs[VCPU_REGS_RDX]; io_dir_in = 0; - do_io: if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in, + do_io: + if (!emulator_io_permited(ctxt, ops, port, + (c->d & ByteOp) ? 1 : c->op_bytes)) { + kvm_inject_gp(ctxt->vcpu, 0); + goto done; + } + if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in, (c->d & ByteOp) ? 1 : c->op_bytes, port) != 0) { c->eip = saved_eip; @@ -2098,13 +2225,21 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) c->dst.type = OP_NONE; /* Disable writeback. */ break; case 0xfa: /* cli */ - ctxt->eflags &= ~X86_EFLAGS_IF; - c->dst.type = OP_NONE; /* Disable writeback. */ + if (emulator_bad_iopl(ctxt)) + kvm_inject_gp(ctxt->vcpu, 0); + else { + ctxt->eflags &= ~X86_EFLAGS_IF; + c->dst.type = OP_NONE; /* Disable writeback. */ + } break; case 0xfb: /* sti */ - toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); - ctxt->eflags |= X86_EFLAGS_IF; - c->dst.type = OP_NONE; /* Disable writeback. */ + if (emulator_bad_iopl(ctxt)) + kvm_inject_gp(ctxt->vcpu, 0); + else { + toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); + ctxt->eflags |= X86_EFLAGS_IF; + c->dst.type = OP_NONE; /* Disable writeback. */ + } break; case 0xfc: /* cld */ ctxt->eflags &= ~EFLG_DF; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 3a01519a49f2..fdf2e28f3bc6 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -136,12 +136,6 @@ module_param(oos_shadow, bool, 0644); #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ | PT64_NX_MASK) -#define PFERR_PRESENT_MASK (1U << 0) -#define PFERR_WRITE_MASK (1U << 1) -#define PFERR_USER_MASK (1U << 2) -#define PFERR_RSVD_MASK (1U << 3) -#define PFERR_FETCH_MASK (1U << 4) - #define PT_PDPE_LEVEL 3 #define PT_DIRECTORY_LEVEL 2 #define PT_PAGE_TABLE_LEVEL 1 @@ -227,7 +221,7 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, } EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes); -static int is_write_protection(struct kvm_vcpu *vcpu) +static bool is_write_protection(struct kvm_vcpu *vcpu) { return vcpu->arch.cr0 & X86_CR0_WP; } @@ -1502,8 +1496,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm, for_each_sp(pages, sp, parents, i) { kvm_mmu_zap_page(kvm, sp); mmu_pages_clear_parents(&parents); + zapped++; } - zapped += pages.nr; kvm_mmu_pages_init(parent, &parents, &pages); } @@ -1554,14 +1548,16 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages) */ if (used_pages > kvm_nr_mmu_pages) { - while (used_pages > kvm_nr_mmu_pages) { + while (used_pages > kvm_nr_mmu_pages && + !list_empty(&kvm->arch.active_mmu_pages)) { struct kvm_mmu_page *page; page = container_of(kvm->arch.active_mmu_pages.prev, struct kvm_mmu_page, link); - kvm_mmu_zap_page(kvm, page); + used_pages -= kvm_mmu_zap_page(kvm, page); used_pages--; } + kvm_nr_mmu_pages = used_pages; kvm->arch.n_free_mmu_pages = 0; } else @@ -1608,7 +1604,8 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn) && !sp->role.invalid) { pgprintk("%s: zap %lx %x\n", __func__, gfn, sp->role.word); - kvm_mmu_zap_page(kvm, sp); + if (kvm_mmu_zap_page(kvm, sp)) + nn = bucket->first; } } } @@ -1639,7 +1636,7 @@ struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva) { struct page *page; - gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); + gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL); if (gpa == UNMAPPED_GVA) return NULL; @@ -1846,6 +1843,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, spte |= PT_WRITABLE_MASK; + if (!tdp_enabled && !(pte_access & ACC_WRITE_MASK)) + spte &= ~PT_USER_MASK; + /* * Optimization: for pte sync, if spte was writable the hash * lookup is unnecessary (and expensive). Write protection @@ -1901,6 +1901,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, child = page_header(pte & PT64_BASE_ADDR_MASK); mmu_page_remove_parent_pte(child, sptep); + __set_spte(sptep, shadow_trap_nonpresent_pte); + kvm_flush_remote_tlbs(vcpu->kvm); } else if (pfn != spte_to_pfn(*sptep)) { pgprintk("hfn old %lx new %lx\n", spte_to_pfn(*sptep), pfn); @@ -2094,11 +2096,13 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) direct = 1; if (mmu_check_root(vcpu, root_gfn)) return 1; + spin_lock(&vcpu->kvm->mmu_lock); sp = kvm_mmu_get_page(vcpu, root_gfn, 0, PT64_ROOT_LEVEL, direct, ACC_ALL, NULL); root = __pa(sp->spt); ++sp->root_count; + spin_unlock(&vcpu->kvm->mmu_lock); vcpu->arch.mmu.root_hpa = root; return 0; } @@ -2120,11 +2124,14 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) root_gfn = 0; if (mmu_check_root(vcpu, root_gfn)) return 1; + spin_lock(&vcpu->kvm->mmu_lock); sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL, direct, ACC_ALL, NULL); root = __pa(sp->spt); ++sp->root_count; + spin_unlock(&vcpu->kvm->mmu_lock); + vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK; } vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root); @@ -2162,8 +2169,11 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu) spin_unlock(&vcpu->kvm->mmu_lock); } -static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr) +static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr, + u32 access, u32 *error) { + if (error) + *error = 0; return vaddr; } @@ -2445,6 +2455,7 @@ static int init_kvm_softmmu(struct kvm_vcpu *vcpu) r = paging32_init_context(vcpu); vcpu->arch.mmu.base_role.glevels = vcpu->arch.mmu.root_level; + vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu); return r; } @@ -2484,7 +2495,9 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu) goto out; spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu); + spin_unlock(&vcpu->kvm->mmu_lock); r = mmu_alloc_roots(vcpu); + spin_lock(&vcpu->kvm->mmu_lock); mmu_sync_roots(vcpu); spin_unlock(&vcpu->kvm->mmu_lock); if (r) @@ -2747,7 +2760,7 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva) if (tdp_enabled) return 0; - gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); + gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL); spin_lock(&vcpu->kvm->mmu_lock); r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT); @@ -3245,7 +3258,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, if (is_shadow_present_pte(ent) && !is_last_spte(ent, level)) audit_mappings_page(vcpu, ent, va, level - 1); else { - gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va); + gpa_t gpa = kvm_mmu_gva_to_gpa_read(vcpu, va, NULL); gfn_t gfn = gpa >> PAGE_SHIFT; pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn); hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT; diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 61a1b3884b49..bac752946368 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -37,6 +37,12 @@ #define PT32_ROOT_LEVEL 2 #define PT32E_ROOT_LEVEL 3 +#define PFERR_PRESENT_MASK (1U << 0) +#define PFERR_WRITE_MASK (1U << 1) +#define PFERR_USER_MASK (1U << 2) +#define PFERR_RSVD_MASK (1U << 3) +#define PFERR_FETCH_MASK (1U << 4) + int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]); static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 5fa33255348c..3bc270766f47 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -318,8 +318,32 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, break; } - if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep)) - continue; + if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep)) { + struct kvm_mmu_page *child; + unsigned direct_access; + + if (level != gw->level) + continue; + + /* + * For the direct sp, if the guest pte's dirty bit + * changed form clean to dirty, it will corrupt the + * sp's access: allow writable in the read-only sp, + * so we should update the spte at this point to get + * a new sp with the correct access. + */ + direct_access = gw->pt_access & gw->pte_access; + if (!is_dirty_gpte(gw->ptes[gw->level - 1])) + direct_access &= ~ACC_WRITE_MASK; + + child = page_header(*sptep & PT64_BASE_ADDR_MASK); + if (child->role.access == direct_access) + continue; + + mmu_page_remove_parent_pte(child, sptep); + __set_spte(sptep, shadow_trap_nonpresent_pte); + kvm_flush_remote_tlbs(vcpu->kvm); + } if (is_large_pte(*sptep)) { rmap_remove(vcpu->kvm, sptep); @@ -336,6 +360,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, /* advance table_gfn when emulating 1gb pages with 4k */ if (delta == 0) table_gfn += PT_INDEX(addr, level); + access &= gw->pte_access; } else { direct = 0; table_gfn = gw->table_gfn[level - 2]; @@ -491,18 +516,23 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) spin_unlock(&vcpu->kvm->mmu_lock); } -static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) +static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, + u32 *error) { struct guest_walker walker; gpa_t gpa = UNMAPPED_GVA; int r; - r = FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0); + r = FNAME(walk_addr)(&walker, vcpu, vaddr, + !!(access & PFERR_WRITE_MASK), + !!(access & PFERR_USER_MASK), + !!(access & PFERR_FETCH_MASK)); if (r) { gpa = gfn_to_gpa(walker.gfn); gpa |= vaddr & ~PAGE_MASK; - } + } else if (error) + *error = walker.error_code; return gpa; } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c17404add91f..253153d2e3e2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -62,6 +63,8 @@ MODULE_LICENSE("GPL"); #define nsvm_printk(fmt, args...) do {} while(0) #endif +static bool erratum_383_found __read_mostly; + static const u32 host_save_user_msrs[] = { #ifdef CONFIG_X86_64 MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, @@ -299,6 +302,31 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) svm_set_interrupt_shadow(vcpu, 0); } +static void svm_init_erratum_383(void) +{ + u32 low, high; + int err; + u64 val; + + /* Only Fam10h is affected */ + if (boot_cpu_data.x86 != 0x10) + return; + + /* Use _safe variants to not break nested virtualization */ + val = native_read_msr_safe(MSR_AMD64_DC_CFG, &err); + if (err) + return; + + val |= (1ULL << 47); + + low = lower_32_bits(val); + high = upper_32_bits(val); + + native_write_msr_safe(MSR_AMD64_DC_CFG, low, high); + + erratum_383_found = true; +} + static int has_svm(void) { const char *msg; @@ -318,7 +346,6 @@ static void svm_hardware_disable(void *garbage) static void svm_hardware_enable(void *garbage) { - struct svm_cpu_data *svm_data; uint64_t efer; struct descriptor_table gdt_descr; @@ -350,6 +377,10 @@ static void svm_hardware_enable(void *garbage) wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(svm_data->save_area) << PAGE_SHIFT); + + svm_init_erratum_383(); + + return; } static void svm_cpu_uninit(int cpu) @@ -590,7 +621,6 @@ static void init_vmcb(struct vcpu_svm *svm) control->iopm_base_pa = iopm_base; control->msrpm_base_pa = __pa(svm->msrpm); - control->tsc_offset = 0; control->int_ctl = V_INTR_MASKING_MASK; init_seg(&save->es); @@ -625,11 +655,12 @@ static void init_vmcb(struct vcpu_svm *svm) save->rip = 0x0000fff0; svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip; - /* - * cr0 val on cpu init should be 0x60000010, we enable cpu - * cache by default. the orderly way is to enable cache in bios. + /* This is the guest-visible cr0 value. + * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. */ - save->cr0 = 0x00000010 | X86_CR0_PG | X86_CR0_WP; + svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; + kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0); + save->cr4 = X86_CR4_PAE; /* rdx = ?? */ @@ -693,29 +724,28 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) if (err) goto free_svm; - page = alloc_page(GFP_KERNEL); - if (!page) { - err = -ENOMEM; - goto uninit; - } - err = -ENOMEM; + page = alloc_page(GFP_KERNEL); + if (!page) + goto uninit; + msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); if (!msrpm_pages) - goto uninit; + goto free_page1; nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); if (!nested_msrpm_pages) - goto uninit; - - svm->msrpm = page_address(msrpm_pages); - svm_vcpu_init_msrpm(svm->msrpm); + goto free_page2; hsave_page = alloc_page(GFP_KERNEL); if (!hsave_page) - goto uninit; + goto free_page3; + svm->nested.hsave = page_address(hsave_page); + svm->msrpm = page_address(msrpm_pages); + svm_vcpu_init_msrpm(svm->msrpm); + svm->nested.msrpm = page_address(nested_msrpm_pages); svm->vmcb = page_address(page); @@ -723,6 +753,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; svm->asid_generation = 0; init_vmcb(svm); + svm->vmcb->control.tsc_offset = 0-native_read_tsc(); fx_init(&svm->vcpu); svm->vcpu.fpu_active = 1; @@ -732,6 +763,12 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) return &svm->vcpu; +free_page3: + __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER); +free_page2: + __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER); +free_page1: + __free_page(page); uninit: kvm_vcpu_uninit(&svm->vcpu); free_svm: @@ -758,17 +795,18 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) int i; if (unlikely(cpu != vcpu->cpu)) { - u64 tsc_this, delta; + u64 delta; - /* - * Make sure that the guest sees a monotonically - * increasing TSC. - */ - rdtscll(tsc_this); - delta = vcpu->arch.host_tsc - tsc_this; - svm->vmcb->control.tsc_offset += delta; - if (is_nested(svm)) - svm->nested.hsave->control.tsc_offset += delta; + if (check_tsc_unstable()) { + /* + * Make sure that the guest sees a monotonically + * increasing TSC. + */ + delta = vcpu->arch.host_tsc - native_read_tsc(); + svm->vmcb->control.tsc_offset += delta; + if (is_nested(svm)) + svm->nested.hsave->control.tsc_offset += delta; + } vcpu->cpu = cpu; kvm_migrate_timers(vcpu); svm->asid_generation = 0; @@ -1251,8 +1289,59 @@ static int nm_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) return 1; } -static int mc_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +static bool is_erratum_383(void) { + int err, i; + u64 value; + + if (!erratum_383_found) + return false; + + value = native_read_msr_safe(MSR_IA32_MC0_STATUS, &err); + if (err) + return false; + + /* Bit 62 may or may not be set for this mce */ + value &= ~(1ULL << 62); + + if (value != 0xb600000000010015ULL) + return false; + + /* Clear MCi_STATUS registers */ + for (i = 0; i < 6; ++i) + native_write_msr_safe(MSR_IA32_MCx_STATUS(i), 0, 0); + + value = native_read_msr_safe(MSR_IA32_MCG_STATUS, &err); + if (!err) { + u32 low, high; + + value &= ~(1ULL << 2); + low = lower_32_bits(value); + high = upper_32_bits(value); + + native_write_msr_safe(MSR_IA32_MCG_STATUS, low, high); + } + + /* Flush tlb to evict multi-match entries */ + __flush_tlb_all(); + + return true; +} + +static void svm_handle_mce(struct vcpu_svm *svm) +{ + if (is_erratum_383()) { + /* + * Erratum 383 triggered. Guest state is corrupt so kill the + * guest. + */ + pr_err("KVM: Guest triggered AMD Erratum 383\n"); + + set_bit(KVM_REQ_TRIPLE_FAULT, &svm->vcpu.requests); + + return; + } + /* * On an #MC intercept the MCE handler is not called automatically in * the host. So do it by hand here. @@ -1261,6 +1350,11 @@ static int mc_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) "int $0x12\n"); /* not sure if we ever come back to this point */ + return; +} + +static int mc_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) +{ return 1; } @@ -2018,7 +2112,7 @@ static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) static int iret_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) { ++svm->vcpu.stat.nmi_window_exits; - svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET); + svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET); svm->vcpu.arch.hflags |= HF_IRET_MASK; return 1; } @@ -2413,7 +2507,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI; vcpu->arch.hflags |= HF_NMI_MASK; - svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET); + svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET); ++vcpu->stat.nmi_injections; } @@ -2604,8 +2698,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) sync_lapic_to_cr8(vcpu); save_host_msrs(vcpu); - fs_selector = kvm_read_fs(); - gs_selector = kvm_read_gs(); + savesegment(fs, fs_selector); + savesegment(gs, gs_selector); ldt_selector = kvm_read_ldt(); svm->vmcb->save.cr2 = vcpu->arch.cr2; /* required for live migration with NPT */ @@ -2692,10 +2786,15 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; - kvm_load_fs(fs_selector); - kvm_load_gs(gs_selector); - kvm_load_ldt(ldt_selector); load_host_msrs(vcpu); + loadsegment(fs, fs_selector); +#ifdef CONFIG_X86_64 + load_gs_index(gs_selector); + wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); +#else + loadsegment(gs, gs_selector); +#endif + kvm_load_ldt(ldt_selector); reload_tss(vcpu); @@ -2711,6 +2810,14 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR); vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR); } + + /* + * We need to handle MC intercepts here before the vcpu has a chance to + * change the physical cpu + */ + if (unlikely(svm->vmcb->control.exit_code == + SVM_EXIT_EXCP_BASE + MC_VECTOR)) + svm_handle_mce(svm); } #undef R diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ed53b42caba1..d9c4fb6f0ff3 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "kvm_cache_regs.h" #include "x86.h" @@ -61,6 +62,8 @@ module_param_named(unrestricted_guest, static int __read_mostly emulate_invalid_guest_state = 0; module_param(emulate_invalid_guest_state, bool, S_IRUGO); +#define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM)) + struct vmcs { u32 revision_id; u32 abort; @@ -92,7 +95,7 @@ struct vcpu_vmx { } host_state; struct { int vm86_active; - u8 save_iopl; + ulong save_rflags; struct kvm_save_segment { u16 selector; unsigned long base; @@ -127,6 +130,7 @@ static u64 construct_eptp(unsigned long root_hpa); static DEFINE_PER_CPU(struct vmcs *, vmxarea); static DEFINE_PER_CPU(struct vmcs *, current_vmcs); static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu); +static DEFINE_PER_CPU(struct desc_ptr, host_gdt); static unsigned long *vmx_io_bitmap_a; static unsigned long *vmx_io_bitmap_b; @@ -625,7 +629,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) */ vmx->host_state.ldt_sel = kvm_read_ldt(); vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; - vmx->host_state.fs_sel = kvm_read_fs(); + savesegment(fs, vmx->host_state.fs_sel); if (!(vmx->host_state.fs_sel & 7)) { vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); vmx->host_state.fs_reload_needed = 0; @@ -633,7 +637,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) vmcs_write16(HOST_FS_SELECTOR, 0); vmx->host_state.fs_reload_needed = 1; } - vmx->host_state.gs_sel = kvm_read_gs(); + savesegment(gs, vmx->host_state.gs_sel); if (!(vmx->host_state.gs_sel & 7)) vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel); else { @@ -650,10 +654,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) #endif #ifdef CONFIG_X86_64 - if (is_long_mode(&vmx->vcpu)) - save_msrs(vmx->host_msrs + - vmx->msr_offset_kernel_gs_base, 1); - + save_msrs(vmx->host_msrs + vmx->msr_offset_kernel_gs_base, 1); #endif load_msrs(vmx->guest_msrs, vmx->save_nmsrs); load_transition_efer(vmx); @@ -661,32 +662,36 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) static void __vmx_load_host_state(struct vcpu_vmx *vmx) { - unsigned long flags; - if (!vmx->host_state.loaded) return; ++vmx->vcpu.stat.host_state_reload; vmx->host_state.loaded = 0; if (vmx->host_state.fs_reload_needed) - kvm_load_fs(vmx->host_state.fs_sel); + loadsegment(fs, vmx->host_state.fs_sel); +#ifdef CONFIG_X86_64 + if (is_long_mode(&vmx->vcpu)) + save_msrs(vmx->guest_msrs + vmx->msr_offset_kernel_gs_base, 1); +#endif if (vmx->host_state.gs_ldt_reload_needed) { kvm_load_ldt(vmx->host_state.ldt_sel); - /* - * If we have to reload gs, we must take care to - * preserve our gs base. - */ - local_irq_save(flags); - kvm_load_gs(vmx->host_state.gs_sel); #ifdef CONFIG_X86_64 - wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); + load_gs_index(vmx->host_state.gs_sel); +#else + loadsegment(gs, vmx->host_state.gs_sel); #endif - local_irq_restore(flags); } reload_tss(); +#ifdef CONFIG_X86_64 + save_msrs(vmx->guest_msrs, vmx->msr_offset_kernel_gs_base); + save_msrs(vmx->guest_msrs + vmx->msr_offset_kernel_gs_base + 1, + vmx->save_nmsrs - vmx->msr_offset_kernel_gs_base - 1); +#else save_msrs(vmx->guest_msrs, vmx->save_nmsrs); +#endif load_msrs(vmx->host_msrs, vmx->save_nmsrs); reload_host_efer(vmx); + load_gdt(&__get_cpu_var(host_gdt)); } static void vmx_load_host_state(struct vcpu_vmx *vmx) @@ -783,18 +788,23 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) { - unsigned long rflags; + unsigned long rflags, save_rflags; rflags = vmcs_readl(GUEST_RFLAGS); - if (to_vmx(vcpu)->rmode.vm86_active) - rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM); + if (to_vmx(vcpu)->rmode.vm86_active) { + rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS; + save_rflags = to_vmx(vcpu)->rmode.save_rflags; + rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; + } return rflags; } static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) { - if (to_vmx(vcpu)->rmode.vm86_active) + if (to_vmx(vcpu)->rmode.vm86_active) { + to_vmx(vcpu)->rmode.save_rflags = rflags; rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; + } vmcs_writel(GUEST_RFLAGS, rflags); } @@ -1133,9 +1143,16 @@ static __init int vmx_disabled_by_bios(void) u64 msr; rdmsrl(MSR_IA32_FEATURE_CONTROL, msr); - return (msr & (FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED)) - == FEATURE_CONTROL_LOCKED; + if (msr & FEATURE_CONTROL_LOCKED) { + if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX) + && tboot_enabled()) + return 1; + if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX) + && !tboot_enabled()) + return 1; + } + + return 0; /* locked but not enabled */ } @@ -1143,22 +1160,26 @@ static void hardware_enable(void *garbage) { int cpu = raw_smp_processor_id(); u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); - u64 old; + u64 old, test_bits; INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); rdmsrl(MSR_IA32_FEATURE_CONTROL, old); - if ((old & (FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED)) - != (FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED)) + + test_bits = FEATURE_CONTROL_LOCKED; + test_bits |= FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX; + if (tboot_enabled()) + test_bits |= FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX; + + if ((old & test_bits) != test_bits) { /* enable and lock */ - wrmsrl(MSR_IA32_FEATURE_CONTROL, old | - FEATURE_CONTROL_LOCKED | - FEATURE_CONTROL_VMXON_ENABLED); + wrmsrl(MSR_IA32_FEATURE_CONTROL, old | test_bits); + } write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr) : "memory", "cc"); + + store_gdt(&__get_cpu_var(host_gdt)); } static void vmclear_local_vcpus(void) @@ -1431,8 +1452,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu) vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar); flags = vmcs_readl(GUEST_RFLAGS); - flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM); - flags |= (vmx->rmode.save_iopl << IOPL_SHIFT); + flags &= RMODE_GUEST_OWNED_EFLAGS_BITS; + flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; vmcs_writel(GUEST_RFLAGS, flags); vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | @@ -1501,8 +1522,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu) vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); flags = vmcs_readl(GUEST_RFLAGS); - vmx->rmode.save_iopl - = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; + vmx->rmode.save_rflags = flags; flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; @@ -2302,8 +2322,10 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; if (vmx->vpid == 0) exec_control &= ~SECONDARY_EXEC_ENABLE_VPID; - if (!enable_ept) + if (!enable_ept) { exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; + enable_unrestricted_guest = 0; + } if (!enable_unrestricted_guest) exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST; vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); @@ -2320,8 +2342,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ - vmcs_write16(HOST_FS_SELECTOR, kvm_read_fs()); /* 22.2.4 */ - vmcs_write16(HOST_GS_SELECTOR, kvm_read_gs()); /* 22.2.4 */ + vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */ + vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */ vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ #ifdef CONFIG_X86_64 rdmsrl(MSR_FS_BASE, a); @@ -2510,7 +2532,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) if (vmx->vpid != 0) vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid); - vmx->vcpu.arch.cr0 = 0x60000010; + vmx->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; vmx_set_cr0(&vmx->vcpu, vmx->vcpu.arch.cr0); /* enter rmode */ vmx_set_cr4(&vmx->vcpu, 0); vmx_set_efer(&vmx->vcpu, 0); @@ -2674,6 +2696,12 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, kvm_queue_exception(vcpu, vec); return 1; case BP_VECTOR: + /* + * Update instruction length as we may reinject the exception + * from user space while in guest debugging mode. + */ + to_vmx(vcpu)->vcpu.arch.event_exit_inst_len = + vmcs_read32(VM_EXIT_INSTRUCTION_LEN); if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) return 0; /* fall through */ @@ -2790,6 +2818,13 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7); /* fall through */ case BP_VECTOR: + /* + * Update instruction length as we may reinject #BP from + * user space while in guest debugging mode. Reading it for + * #DB as well causes no harm, it is not used in that case. + */ + vmx->vcpu.arch.event_exit_inst_len = + vmcs_read32(VM_EXIT_INSTRUCTION_LEN); kvm_run->exit_reason = KVM_EXIT_DEBUG; kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip; kvm_run->debug.arch.exception = ex_no; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e78d9907e0ee..b2c02a2b0038 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -297,21 +297,16 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu) void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { if (cr0 & CR0_RESERVED_BITS) { - printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n", - cr0, vcpu->arch.cr0); kvm_inject_gp(vcpu, 0); return; } if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) { - printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n"); kvm_inject_gp(vcpu, 0); return; } if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) { - printk(KERN_DEBUG "set_cr0: #GP, set PG flag " - "and a clear PE flag\n"); kvm_inject_gp(vcpu, 0); return; } @@ -322,15 +317,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) int cs_db, cs_l; if (!is_pae(vcpu)) { - printk(KERN_DEBUG "set_cr0: #GP, start paging " - "in long mode while PAE is disabled\n"); kvm_inject_gp(vcpu, 0); return; } kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); if (cs_l) { - printk(KERN_DEBUG "set_cr0: #GP, start paging " - "in long mode while CS.L == 1\n"); kvm_inject_gp(vcpu, 0); return; @@ -338,8 +329,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } else #endif if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) { - printk(KERN_DEBUG "set_cr0: #GP, pdptrs " - "reserved bits\n"); kvm_inject_gp(vcpu, 0); return; } @@ -356,7 +345,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0); void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) { - kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)); + kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0eul) | (msw & 0x0f)); } EXPORT_SYMBOL_GPL(kvm_lmsw); @@ -366,28 +355,23 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE; if (cr4 & CR4_RESERVED_BITS) { - printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n"); kvm_inject_gp(vcpu, 0); return; } if (is_long_mode(vcpu)) { if (!(cr4 & X86_CR4_PAE)) { - printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while " - "in long mode\n"); kvm_inject_gp(vcpu, 0); return; } } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE) && ((cr4 ^ old_cr4) & pdptr_bits) && !load_pdptrs(vcpu, vcpu->arch.cr3)) { - printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n"); kvm_inject_gp(vcpu, 0); return; } if (cr4 & X86_CR4_VMXE) { - printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n"); kvm_inject_gp(vcpu, 0); return; } @@ -408,21 +392,16 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) if (is_long_mode(vcpu)) { if (cr3 & CR3_L_MODE_RESERVED_BITS) { - printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); kvm_inject_gp(vcpu, 0); return; } } else { if (is_pae(vcpu)) { if (cr3 & CR3_PAE_RESERVED_BITS) { - printk(KERN_DEBUG - "set_cr3: #GP, reserved bits\n"); kvm_inject_gp(vcpu, 0); return; } if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) { - printk(KERN_DEBUG "set_cr3: #GP, pdptrs " - "reserved bits\n"); kvm_inject_gp(vcpu, 0); return; } @@ -454,7 +433,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr3); void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) { if (cr8 & CR8_RESERVED_BITS) { - printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8); kvm_inject_gp(vcpu, 0); return; } @@ -505,53 +483,42 @@ static u32 emulated_msrs[] = { MSR_IA32_MISC_ENABLE, }; -static void set_efer(struct kvm_vcpu *vcpu, u64 efer) +static int set_efer(struct kvm_vcpu *vcpu, u64 efer) { - if (efer & efer_reserved_bits) { - printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n", - efer); - kvm_inject_gp(vcpu, 0); - return; - } + if (efer & efer_reserved_bits) + return 1; if (is_paging(vcpu) - && (vcpu->arch.shadow_efer & EFER_LME) != (efer & EFER_LME)) { - printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n"); - kvm_inject_gp(vcpu, 0); - return; - } + && (vcpu->arch.shadow_efer & EFER_LME) != (efer & EFER_LME)) + return 1; if (efer & EFER_FFXSR) { struct kvm_cpuid_entry2 *feat; feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); - if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) { - printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n"); - kvm_inject_gp(vcpu, 0); - return; - } + if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) + return 1; } if (efer & EFER_SVME) { struct kvm_cpuid_entry2 *feat; feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); - if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) { - printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n"); - kvm_inject_gp(vcpu, 0); - return; - } + if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) + return 1; } - kvm_x86_ops->set_efer(vcpu, efer); - efer &= ~EFER_LMA; efer |= vcpu->arch.shadow_efer & EFER_LMA; + kvm_x86_ops->set_efer(vcpu, efer); + vcpu->arch.shadow_efer = efer; vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled; kvm_mmu_reset_context(vcpu); + + return 0; } void kvm_enable_efer_bits(u64 mask) @@ -581,14 +548,22 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) { - static int version; + int version; + int r; struct pvclock_wall_clock wc; struct timespec boot; if (!wall_clock) return; - version++; + r = kvm_read_guest(kvm, wall_clock, &version, sizeof(version)); + if (r) + return; + + if (version & 1) + ++version; /* first time write, random junk */ + + ++version; kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); @@ -826,9 +801,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data) if (msr >= MSR_IA32_MC0_CTL && msr < MSR_IA32_MC0_CTL + 4 * bank_num) { u32 offset = msr - MSR_IA32_MC0_CTL; - /* only 0 or all 1s can be written to IA32_MCi_CTL */ + /* only 0 or all 1s can be written to IA32_MCi_CTL + * some Linux kernels though clear bit 10 in bank 4 to + * workaround a BIOS/GART TBL issue on AMD K8s, ignore + * this to avoid an uncatched #GP in the guest + */ if ((offset & 0x3) == 0 && - data != 0 && data != ~(u64)0) + data != 0 && (data | (1 << 10)) != ~(u64)0) return -1; vcpu->arch.mce_banks[offset] = data; break; @@ -842,8 +821,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) { switch (msr) { case MSR_EFER: - set_efer(vcpu, data); - break; + return set_efer(vcpu, data); case MSR_K7_HWCR: data &= ~(u64)0x40; /* ignore flush filter disable */ if (data != 0) { @@ -1242,8 +1220,8 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_NR_MEMSLOTS: r = KVM_MEMORY_SLOTS; break; - case KVM_CAP_PV_MMU: - r = !tdp_enabled; + case KVM_CAP_PV_MMU: /* obsolete */ + r = 0; break; case KVM_CAP_IOMMU: r = iommu_found(); @@ -1435,6 +1413,7 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, { int r; + vcpu_load(vcpu); r = -E2BIG; if (cpuid->nent < vcpu->arch.cpuid_nent) goto out; @@ -1446,6 +1425,7 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, out: cpuid->nent = vcpu->arch.cpuid_nent; + vcpu_put(vcpu); return r; } @@ -1505,7 +1485,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, const u32 kvm_supported_word6_x86_features = F(LAHF_LM) | F(CMP_LEGACY) | F(SVM) | 0 /* ExtApicSpace */ | F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) | - F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(SSE5) | + F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(XOP) | 0 /* SKINIT */ | 0 /* WDT */; /* all calls to cpuid_count() should be made on the same cpu */ @@ -1695,6 +1675,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, int r; unsigned bank_num = mcg_cap & 0xff, bank; + vcpu_load(vcpu); r = -EINVAL; if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS) goto out; @@ -1709,6 +1690,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, for (bank = 0; bank < bank_num; bank++) vcpu->arch.mce_banks[bank*4] = ~(u64)0; out: + vcpu_put(vcpu); return r; } @@ -1911,7 +1893,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&mce, argp, sizeof mce)) goto out; + vcpu_load(vcpu); r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce); + vcpu_put(vcpu); break; } default: @@ -2118,6 +2102,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) sizeof(ps->channels)); ps->flags = kvm->arch.vpit->pit_state.flags; mutex_unlock(&kvm->arch.vpit->pit_state.lock); + memset(&ps->reserved, 0, sizeof(ps->reserved)); return r; } @@ -2156,7 +2141,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) { int r; - int n; + unsigned long n; struct kvm_memory_slot *memslot; int is_dirty = 0; @@ -2172,7 +2157,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, kvm_mmu_slot_remove_write_access(kvm, log->slot); spin_unlock(&kvm->mmu_lock); memslot = &kvm->memslots[log->slot]; - n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; + n = kvm_dirty_bitmap_bytes(memslot); memset(memslot->dirty_bitmap, 0, n); } r = 0; @@ -2455,6 +2440,7 @@ long kvm_arch_vm_ioctl(struct file *filp, now_ns = timespec_to_ns(&now); user_ns.clock = kvm->arch.kvmclock_offset + now_ns; user_ns.flags = 0; + memset(&user_ns.pad, 0, sizeof(user_ns.pad)); r = -EFAULT; if (copy_to_user(argp, &user_ns, sizeof(user_ns))) @@ -2505,14 +2491,41 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) return kvm_io_bus_read(&vcpu->kvm->mmio_bus, addr, len, v); } -static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, - struct kvm_vcpu *vcpu) +gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) +{ + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error); +} + + gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) +{ + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + access |= PFERR_FETCH_MASK; + return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error); +} + +gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) +{ + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + access |= PFERR_WRITE_MASK; + return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, access, error); +} + +/* uses this to access any guest's mapped memory without checking CPL */ +gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) +{ + return vcpu->arch.mmu.gva_to_gpa(vcpu, gva, 0, error); +} + +static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, + struct kvm_vcpu *vcpu, u32 access, + u32 *error) { void *data = val; int r = X86EMUL_CONTINUE; while (bytes) { - gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, access, error); unsigned offset = addr & (PAGE_SIZE-1); unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -2535,14 +2548,37 @@ static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, return r; } +/* used for instruction fetching */ +static int kvm_fetch_guest_virt(gva_t addr, void *val, unsigned int bytes, + struct kvm_vcpu *vcpu, u32 *error) +{ + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, + access | PFERR_FETCH_MASK, error); +} + +static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, + struct kvm_vcpu *vcpu, u32 *error) +{ + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, + error); +} + +static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes, + struct kvm_vcpu *vcpu, u32 *error) +{ + return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error); +} + static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes, - struct kvm_vcpu *vcpu) + struct kvm_vcpu *vcpu, u32 *error) { void *data = val; int r = X86EMUL_CONTINUE; while (bytes) { - gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + gpa_t gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error); unsigned offset = addr & (PAGE_SIZE-1); unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); int ret; @@ -2572,6 +2608,7 @@ static int emulator_read_emulated(unsigned long addr, struct kvm_vcpu *vcpu) { gpa_t gpa; + u32 error_code; if (vcpu->mmio_read_completed) { memcpy(val, vcpu->mmio_data, bytes); @@ -2581,17 +2618,20 @@ static int emulator_read_emulated(unsigned long addr, return X86EMUL_CONTINUE; } - gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, &error_code); + + if (gpa == UNMAPPED_GVA) { + kvm_inject_page_fault(vcpu, addr, error_code); + return X86EMUL_PROPAGATE_FAULT; + } /* For APIC access vmexit */ if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) goto mmio; - if (kvm_read_guest_virt(addr, val, bytes, vcpu) + if (kvm_read_guest_virt(addr, val, bytes, vcpu, NULL) == X86EMUL_CONTINUE) return X86EMUL_CONTINUE; - if (gpa == UNMAPPED_GVA) - return X86EMUL_PROPAGATE_FAULT; mmio: /* @@ -2630,11 +2670,12 @@ static int emulator_write_emulated_onepage(unsigned long addr, struct kvm_vcpu *vcpu) { gpa_t gpa; + u32 error_code; - gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, &error_code); if (gpa == UNMAPPED_GVA) { - kvm_inject_page_fault(vcpu, addr, 2); + kvm_inject_page_fault(vcpu, addr, error_code); return X86EMUL_PROPAGATE_FAULT; } @@ -2698,7 +2739,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr, char *kaddr; u64 val; - gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); + gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL); if (gpa == UNMAPPED_GVA || (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) @@ -2743,6 +2784,9 @@ int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) { struct kvm_vcpu *vcpu = ctxt->vcpu; + if (!kvm_x86_ops->get_dr) + return X86EMUL_UNHANDLEABLE; + switch (dr) { case 0 ... 3: *dest = kvm_x86_ops->get_dr(vcpu, dr); @@ -2758,6 +2802,9 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U; int exception; + if (!kvm_x86_ops->set_dr) + return X86EMUL_UNHANDLEABLE; + kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask, &exception); if (exception) { /* FIXME: better handling */ @@ -2777,7 +2824,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); - kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu); + kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu, NULL); printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); @@ -2785,7 +2832,8 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); static struct x86_emulate_ops emulate_ops = { - .read_std = kvm_read_guest_virt, + .read_std = kvm_read_guest_virt_system, + .fetch = kvm_fetch_guest_virt, .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated, @@ -2828,8 +2876,9 @@ int emulate_instruction(struct kvm_vcpu *vcpu, vcpu->arch.emulate_ctxt.vcpu = vcpu; vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); vcpu->arch.emulate_ctxt.mode = + (!(vcpu->arch.cr0 & X86_CR0_PE)) ? X86EMUL_MODE_REAL : (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) - ? X86EMUL_MODE_REAL : cs_l + ? X86EMUL_MODE_VM86 : cs_l ? X86EMUL_MODE_PROT64 : cs_db ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; @@ -2921,12 +2970,17 @@ static int pio_copy_data(struct kvm_vcpu *vcpu) gva_t q = vcpu->arch.pio.guest_gva; unsigned bytes; int ret; + u32 error_code; bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count; if (vcpu->arch.pio.in) - ret = kvm_write_guest_virt(q, p, bytes, vcpu); + ret = kvm_write_guest_virt(q, p, bytes, vcpu, &error_code); else - ret = kvm_read_guest_virt(q, p, bytes, vcpu); + ret = kvm_read_guest_virt(q, p, bytes, vcpu, &error_code); + + if (ret == X86EMUL_PROPAGATE_FAULT) + kvm_inject_page_fault(vcpu, q, error_code); + return ret; } @@ -2947,7 +3001,7 @@ int complete_pio(struct kvm_vcpu *vcpu) if (io->in) { r = pio_copy_data(vcpu); if (r) - return r; + goto out; } delta = 1; @@ -2974,7 +3028,7 @@ int complete_pio(struct kvm_vcpu *vcpu) kvm_register_write(vcpu, VCPU_REGS_RSI, val); } } - +out: io->count -= io->cur_count; io->cur_count = 0; @@ -3017,6 +3071,8 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, { unsigned long val; + trace_kvm_pio(!in, port, size, 1); + vcpu->run->exit_reason = KVM_EXIT_IO; vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; vcpu->run->io.size = vcpu->arch.pio.size = size; @@ -3028,9 +3084,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, vcpu->arch.pio.down = 0; vcpu->arch.pio.rep = 0; - trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port, - size, 1); - val = kvm_register_read(vcpu, VCPU_REGS_RAX); memcpy(vcpu->arch.pio_data, &val, 4); @@ -3049,6 +3102,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, unsigned now, in_page; int ret = 0; + trace_kvm_pio(!in, port, size, count); + vcpu->run->exit_reason = KVM_EXIT_IO; vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; vcpu->run->io.size = vcpu->arch.pio.size = size; @@ -3060,9 +3115,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, vcpu->arch.pio.down = down; vcpu->arch.pio.rep = rep; - trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port, - size, count); - if (!count) { kvm_x86_ops->skip_emulated_instruction(vcpu); return 1; @@ -3094,10 +3146,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, if (!vcpu->arch.pio.in) { /* string PIO write */ ret = pio_copy_data(vcpu); - if (ret == X86EMUL_PROPAGATE_FAULT) { - kvm_inject_gp(vcpu, 0); + if (ret == X86EMUL_PROPAGATE_FAULT) return 1; - } if (ret == 0 && !pio_string_write(vcpu)) { complete_pio(vcpu); if (vcpu->arch.pio.count == 0) @@ -4077,7 +4127,9 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); return 1; } - return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu); + return kvm_read_guest_virt_system(dtable.base + index*8, + seg_desc, sizeof(*seg_desc), + vcpu, NULL); } /* allowed just for 8 bytes segments */ @@ -4091,15 +4143,23 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, if (dtable.limit < index * 8 + 7) return 1; - return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu); + return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu, NULL); } -static gpa_t get_tss_base_addr(struct kvm_vcpu *vcpu, +static gpa_t get_tss_base_addr_write(struct kvm_vcpu *vcpu, + struct desc_struct *seg_desc) +{ + u32 base_addr = get_desc_base(seg_desc); + + return kvm_mmu_gva_to_gpa_write(vcpu, base_addr, NULL); +} + +static gpa_t get_tss_base_addr_read(struct kvm_vcpu *vcpu, struct desc_struct *seg_desc) { u32 base_addr = get_desc_base(seg_desc); - return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr); + return kvm_mmu_gva_to_gpa_read(vcpu, base_addr, NULL); } static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) @@ -4110,18 +4170,6 @@ static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) return kvm_seg.selector; } -static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu, - u16 selector, - struct kvm_segment *kvm_seg) -{ - struct desc_struct seg_desc; - - if (load_guest_segment_descriptor(vcpu, selector, &seg_desc)) - return 1; - seg_desct_to_kvm_desct(&seg_desc, selector, kvm_seg); - return 0; -} - static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg) { struct kvm_segment segvar = { @@ -4139,7 +4187,7 @@ static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int se .unusable = 0, }; kvm_x86_ops->set_segment(vcpu, &segvar, seg); - return 0; + return X86EMUL_CONTINUE; } static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg) @@ -4149,24 +4197,113 @@ static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg) (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_VM); } -int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, - int type_bits, int seg) +int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg) { struct kvm_segment kvm_seg; + struct desc_struct seg_desc; + u8 dpl, rpl, cpl; + unsigned err_vec = GP_VECTOR; + u32 err_code = 0; + bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */ + int ret; if (is_vm86_segment(vcpu, seg) || !(vcpu->arch.cr0 & X86_CR0_PE)) return kvm_load_realmode_segment(vcpu, selector, seg); - if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) - return 1; - kvm_seg.type |= type_bits; - if (seg != VCPU_SREG_SS && seg != VCPU_SREG_CS && - seg != VCPU_SREG_LDTR) - if (!kvm_seg.s) - kvm_seg.unusable = 1; + /* NULL selector is not valid for TR, CS and SS */ + if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR) + && null_selector) + goto exception; + + /* TR should be in GDT only */ + if (seg == VCPU_SREG_TR && (selector & (1 << 2))) + goto exception; + + ret = load_guest_segment_descriptor(vcpu, selector, &seg_desc); + if (ret) + return ret; + + seg_desct_to_kvm_desct(&seg_desc, selector, &kvm_seg); + + if (null_selector) { /* for NULL selector skip all following checks */ + kvm_seg.unusable = 1; + goto load; + } + + err_code = selector & 0xfffc; + err_vec = GP_VECTOR; + + /* can't load system descriptor into segment selecor */ + if (seg <= VCPU_SREG_GS && !kvm_seg.s) + goto exception; + + if (!kvm_seg.present) { + err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR; + goto exception; + } + + rpl = selector & 3; + dpl = kvm_seg.dpl; + cpl = kvm_x86_ops->get_cpl(vcpu); + + switch (seg) { + case VCPU_SREG_SS: + /* + * segment is not a writable data segment or segment + * selector's RPL != CPL or segment selector's RPL != CPL + */ + if (rpl != cpl || (kvm_seg.type & 0xa) != 0x2 || dpl != cpl) + goto exception; + break; + case VCPU_SREG_CS: + if (!(kvm_seg.type & 8)) + goto exception; + + if (kvm_seg.type & 4) { + /* conforming */ + if (dpl > cpl) + goto exception; + } else { + /* nonconforming */ + if (rpl > cpl || dpl != cpl) + goto exception; + } + /* CS(RPL) <- CPL */ + selector = (selector & 0xfffc) | cpl; + break; + case VCPU_SREG_TR: + if (kvm_seg.s || (kvm_seg.type != 1 && kvm_seg.type != 9)) + goto exception; + break; + case VCPU_SREG_LDTR: + if (kvm_seg.s || kvm_seg.type != 2) + goto exception; + break; + default: /* DS, ES, FS, or GS */ + /* + * segment is not a data or readable code segment or + * ((segment is a data or nonconforming code segment) + * and (both RPL and CPL > DPL)) + */ + if ((kvm_seg.type & 0xa) == 0x8 || + (((kvm_seg.type & 0xc) != 0xc) && (rpl > dpl && cpl > dpl))) + goto exception; + break; + } + + if (!kvm_seg.unusable && kvm_seg.s) { + /* mark segment as accessed */ + kvm_seg.type |= 1; + seg_desc.type |= 1; + save_guest_segment_descriptor(vcpu, selector, &seg_desc); + } +load: kvm_set_segment(vcpu, &kvm_seg, seg); - return 0; + return X86EMUL_CONTINUE; +exception: + kvm_queue_exception_e(vcpu, err_vec, err_code); + return X86EMUL_PROPAGATE_FAULT; } static void save_state_to_tss32(struct kvm_vcpu *vcpu, @@ -4192,6 +4329,14 @@ static void save_state_to_tss32(struct kvm_vcpu *vcpu, tss->ldt_selector = get_segment_selector(vcpu, VCPU_SREG_LDTR); } +static void kvm_load_segment_selector(struct kvm_vcpu *vcpu, u16 sel, int seg) +{ + struct kvm_segment kvm_seg; + kvm_get_segment(vcpu, &kvm_seg, seg); + kvm_seg.selector = sel; + kvm_set_segment(vcpu, &kvm_seg, seg); +} + static int load_state_from_tss32(struct kvm_vcpu *vcpu, struct tss_segment_32 *tss) { @@ -4209,25 +4354,41 @@ static int load_state_from_tss32(struct kvm_vcpu *vcpu, kvm_register_write(vcpu, VCPU_REGS_RSI, tss->esi); kvm_register_write(vcpu, VCPU_REGS_RDI, tss->edi); - if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, 0, VCPU_SREG_LDTR)) + /* + * SDM says that segment selectors are loaded before segment + * descriptors + */ + kvm_load_segment_selector(vcpu, tss->ldt_selector, VCPU_SREG_LDTR); + kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES); + kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS); + kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS); + kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS); + kvm_load_segment_selector(vcpu, tss->fs, VCPU_SREG_FS); + kvm_load_segment_selector(vcpu, tss->gs, VCPU_SREG_GS); + + /* + * Now load segment descriptors. If fault happenes at this stage + * it is handled in a context of new task + */ + if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, VCPU_SREG_LDTR)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES)) + if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS)) + if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS)) + if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS)) + if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->fs, 1, VCPU_SREG_FS)) + if (kvm_load_segment_descriptor(vcpu, tss->fs, VCPU_SREG_FS)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->gs, 1, VCPU_SREG_GS)) + if (kvm_load_segment_descriptor(vcpu, tss->gs, VCPU_SREG_GS)) return 1; return 0; } @@ -4268,19 +4429,33 @@ static int load_state_from_tss16(struct kvm_vcpu *vcpu, kvm_register_write(vcpu, VCPU_REGS_RSI, tss->si); kvm_register_write(vcpu, VCPU_REGS_RDI, tss->di); - if (kvm_load_segment_descriptor(vcpu, tss->ldt, 0, VCPU_SREG_LDTR)) + /* + * SDM says that segment selectors are loaded before segment + * descriptors + */ + kvm_load_segment_selector(vcpu, tss->ldt, VCPU_SREG_LDTR); + kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES); + kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS); + kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS); + kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS); + + /* + * Now load segment descriptors. If fault happenes at this stage + * it is handled in a context of new task + */ + if (kvm_load_segment_descriptor(vcpu, tss->ldt, VCPU_SREG_LDTR)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->es, 1, VCPU_SREG_ES)) + if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->cs, 9, VCPU_SREG_CS)) + if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->ss, 1, VCPU_SREG_SS)) + if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS)) return 1; - if (kvm_load_segment_descriptor(vcpu, tss->ds, 1, VCPU_SREG_DS)) + if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS)) return 1; return 0; } @@ -4302,7 +4477,7 @@ static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, sizeof tss_segment_16)) goto out; - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), + if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc), &tss_segment_16, sizeof tss_segment_16)) goto out; @@ -4310,7 +4485,7 @@ static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, tss_segment_16.prev_task_link = old_tss_sel; if (kvm_write_guest(vcpu->kvm, - get_tss_base_addr(vcpu, nseg_desc), + get_tss_base_addr_write(vcpu, nseg_desc), &tss_segment_16.prev_task_link, sizeof tss_segment_16.prev_task_link)) goto out; @@ -4341,7 +4516,7 @@ static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, sizeof tss_segment_32)) goto out; - if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc), + if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc), &tss_segment_32, sizeof tss_segment_32)) goto out; @@ -4349,7 +4524,7 @@ static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, tss_segment_32.prev_task_link = old_tss_sel; if (kvm_write_guest(vcpu->kvm, - get_tss_base_addr(vcpu, nseg_desc), + get_tss_base_addr_write(vcpu, nseg_desc), &tss_segment_32.prev_task_link, sizeof tss_segment_32.prev_task_link)) goto out; @@ -4371,8 +4546,9 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) int ret = 0; u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR); u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR); + u32 desc_limit; - old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base); + old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL); /* FIXME: Handle errors. Failure to read either TSS or their * descriptors should generate a pagefault. @@ -4393,7 +4569,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) } } - if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) { + desc_limit = get_desc_limit(&nseg_desc); + if (!nseg_desc.p || + ((desc_limit < 0x67 && (nseg_desc.type & 8)) || + desc_limit < 0x2b)) { kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc); return 1; } @@ -4581,7 +4760,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, vcpu_load(vcpu); down_read(&vcpu->kvm->slots_lock); - gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr); + gpa = kvm_mmu_gva_to_gpa_system(vcpu, vaddr, NULL); up_read(&vcpu->kvm->slots_lock); tr->physical_address = gpa; tr->valid = gpa != UNMAPPED_GVA; diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index c2b6f395a022..ac2d426ea35f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for x86 specific library files. # -obj-$(CONFIG_SMP) += msr-smp.o +obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o lib-y := delay.o lib-y += thunk_$(BITS).o @@ -26,4 +26,5 @@ else lib-y += thunk_64.o clear_page_64.o copy_page_64.o lib-y += memmove_64.o memset_64.o lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o + lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o endif diff --git a/arch/x86/lib/cache-smp.c b/arch/x86/lib/cache-smp.c new file mode 100644 index 000000000000..a3c668875038 --- /dev/null +++ b/arch/x86/lib/cache-smp.c @@ -0,0 +1,19 @@ +#include +#include + +static void __wbinvd(void *dummy) +{ + wbinvd(); +} + +void wbinvd_on_cpu(int cpu) +{ + smp_call_function_single(cpu, __wbinvd, NULL, 1); +} +EXPORT_SYMBOL(wbinvd_on_cpu); + +int wbinvd_on_all_cpus(void) +{ + return on_each_cpu(__wbinvd, NULL, 1); +} +EXPORT_SYMBOL(wbinvd_on_all_cpus); diff --git a/arch/x86/lib/rwsem_64.S b/arch/x86/lib/rwsem_64.S new file mode 100644 index 000000000000..15acecf0d7aa --- /dev/null +++ b/arch/x86/lib/rwsem_64.S @@ -0,0 +1,81 @@ +/* + * x86-64 rwsem wrappers + * + * This interfaces the inline asm code to the slow-path + * C routines. We need to save the call-clobbered regs + * that the asm does not mark as clobbered, and move the + * argument from %rax to %rdi. + * + * NOTE! We don't need to save %rax, because the functions + * will always return the semaphore pointer in %rax (which + * is also the input argument to these helpers) + * + * The following can clobber %rdx because the asm clobbers it: + * call_rwsem_down_write_failed + * call_rwsem_wake + * but %rdi, %rsi, %rcx, %r8-r11 always need saving. + */ + +#include +#include +#include +#include +#include + +#define save_common_regs \ + pushq %rdi; \ + pushq %rsi; \ + pushq %rcx; \ + pushq %r8; \ + pushq %r9; \ + pushq %r10; \ + pushq %r11 + +#define restore_common_regs \ + popq %r11; \ + popq %r10; \ + popq %r9; \ + popq %r8; \ + popq %rcx; \ + popq %rsi; \ + popq %rdi + +/* Fix up special calling conventions */ +ENTRY(call_rwsem_down_read_failed) + save_common_regs + pushq %rdx + movq %rax,%rdi + call rwsem_down_read_failed + popq %rdx + restore_common_regs + ret + ENDPROC(call_rwsem_down_read_failed) + +ENTRY(call_rwsem_down_write_failed) + save_common_regs + movq %rax,%rdi + call rwsem_down_write_failed + restore_common_regs + ret + ENDPROC(call_rwsem_down_write_failed) + +ENTRY(call_rwsem_wake) + decw %dx /* do nothing if still outstanding active readers */ + jnz 1f + save_common_regs + movq %rax,%rdi + call rwsem_wake + restore_common_regs +1: ret + ENDPROC(call_rwsem_wake) + +/* Fix up special calling conventions */ +ENTRY(call_rwsem_downgrade_wake) + save_common_regs + pushq %rdx + movq %rax,%rdi + call rwsem_downgrade_wake + popq %rdx + restore_common_regs + ret + ENDPROC(call_rwsem_downgrade_wake) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f4cee9028cf0..1739358b444d 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -801,8 +801,10 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, up_read(&mm->mmap_sem); /* Kernel mode? Handle exceptions or die: */ - if (!(error_code & PF_USER)) + if (!(error_code & PF_USER)) { no_context(regs, error_code, address); + return; + } /* User-space => ok to do another page fault: */ if (is_prefetch(regs, error_code, address)) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 5a4398a6006b..7d095ad54535 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -49,6 +49,7 @@ #include #include #include +#include static unsigned long dma_reserve __initdata; @@ -614,6 +615,21 @@ void __init paging_init(void) * Memory hotplug specific functions */ #ifdef CONFIG_MEMORY_HOTPLUG +/* + * After memory hotplug the variables max_pfn, max_low_pfn and high_memory need + * updating. + */ +static void update_end_of_memory_vars(u64 start, u64 size) +{ + unsigned long end_pfn = PFN_UP(start + size); + + if (end_pfn > max_pfn) { + max_pfn = end_pfn; + max_low_pfn = end_pfn; + high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1; + } +} + /* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. @@ -633,6 +649,9 @@ int arch_add_memory(int nid, u64 start, u64 size) ret = __add_pages(nid, zone, start_pfn, nr_pages); WARN_ON_ONCE(ret); + /* update max_pfn, max_low_pfn and high_memory */ + update_end_of_memory_vars(start, size); + return ret; } EXPORT_SYMBOL_GPL(arch_add_memory); diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index ed34f5e35999..c9ba9deafe83 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -6,6 +6,14 @@ #define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO +#ifdef CONFIG_HIGHPTE +#define PGALLOC_USER_GFP __GFP_HIGHMEM +#else +#define PGALLOC_USER_GFP 0 +#endif + +gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP; + pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { return (pte_t *)__get_free_page(PGALLOC_GFP); @@ -15,16 +23,29 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { struct page *pte; -#ifdef CONFIG_HIGHPTE - pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0); -#else - pte = alloc_pages(PGALLOC_GFP, 0); -#endif + pte = alloc_pages(__userpte_alloc_gfp, 0); if (pte) pgtable_page_ctor(pte); return pte; } +static int __init setup_userpte(char *arg) +{ + if (!arg) + return -EINVAL; + + /* + * "userpte=nohigh" disables allocation of user pagetables in + * high memory. + */ + if (strcmp(arg, "nohigh") == 0) + __userpte_alloc_gfp &= ~__GFP_HIGHMEM; + else + return -EINVAL; + return 0; +} +early_param("userpte", setup_userpte); + void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) { pgtable_page_dtor(pte); diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 3347f696edc7..ca6b33667f54 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -95,7 +95,10 @@ static void nmi_cpu_save_registers(struct op_msrs *msrs) static void nmi_cpu_start(void *dummy) { struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); - model->start(msrs); + if (!msrs->controls) + WARN_ON_ONCE(1); + else + model->start(msrs); } static int nmi_start(void) @@ -107,7 +110,10 @@ static int nmi_start(void) static void nmi_cpu_stop(void *dummy) { struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); - model->stop(msrs); + if (!msrs->controls) + WARN_ON_ONCE(1); + else + model->stop(msrs); } static void nmi_stop(void) @@ -159,7 +165,7 @@ static int nmi_setup_mux(void) for_each_possible_cpu(i) { per_cpu(cpu_msrs, i).multiplex = - kmalloc(multiplex_size, GFP_KERNEL); + kzalloc(multiplex_size, GFP_KERNEL); if (!per_cpu(cpu_msrs, i).multiplex) return 0; } @@ -179,7 +185,6 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) if (counter_config[i].enabled) { multiplex[i].saved = -(u64)counter_config[i].count; } else { - multiplex[i].addr = 0; multiplex[i].saved = 0; } } @@ -189,25 +194,27 @@ static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs) { + struct op_msr *counters = msrs->counters; struct op_msr *multiplex = msrs->multiplex; int i; for (i = 0; i < model->num_counters; ++i) { int virt = op_x86_phys_to_virt(i); - if (multiplex[virt].addr) - rdmsrl(multiplex[virt].addr, multiplex[virt].saved); + if (counters[i].addr) + rdmsrl(counters[i].addr, multiplex[virt].saved); } } static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs) { + struct op_msr *counters = msrs->counters; struct op_msr *multiplex = msrs->multiplex; int i; for (i = 0; i < model->num_counters; ++i) { int virt = op_x86_phys_to_virt(i); - if (multiplex[virt].addr) - wrmsrl(multiplex[virt].addr, multiplex[virt].saved); + if (counters[i].addr) + wrmsrl(counters[i].addr, multiplex[virt].saved); } } @@ -303,11 +310,11 @@ static int allocate_msrs(void) int i; for_each_possible_cpu(i) { - per_cpu(cpu_msrs, i).counters = kmalloc(counters_size, + per_cpu(cpu_msrs, i).counters = kzalloc(counters_size, GFP_KERNEL); if (!per_cpu(cpu_msrs, i).counters) return 0; - per_cpu(cpu_msrs, i).controls = kmalloc(controls_size, + per_cpu(cpu_msrs, i).controls = kzalloc(controls_size, GFP_KERNEL); if (!per_cpu(cpu_msrs, i).controls) return 0; @@ -511,8 +518,13 @@ static int __init init_sysfs(void) int error; error = sysdev_class_register(&oprofile_sysclass); - if (!error) - error = sysdev_register(&device_oprofile); + if (error) + return error; + + error = sysdev_register(&device_oprofile); + if (error) + sysdev_class_unregister(&oprofile_sysclass); + return error; } @@ -523,8 +535,10 @@ static void exit_sysfs(void) } #else -#define init_sysfs() do { } while (0) -#define exit_sysfs() do { } while (0) + +static inline int init_sysfs(void) { return 0; } +static inline void exit_sysfs(void) { } + #endif /* CONFIG_PM */ static int __init p4_init(char **cpu_type) @@ -577,6 +591,18 @@ static int __init ppro_init(char **cpu_type) if (force_arch_perfmon && cpu_has_arch_perfmon) return 0; + /* + * Documentation on identifying Intel processors by CPU family + * and model can be found in the Intel Software Developer's + * Manuals (SDM): + * + * http://www.intel.com/products/processor/manuals/ + * + * As of May 2010 the documentation for this was in the: + * "Intel 64 and IA-32 Architectures Software Developer's + * Manual Volume 3B: System Programming Guide", "Table B-1 + * CPUID Signature Values of DisplayFamily_DisplayModel". + */ switch (cpu_model) { case 0 ... 2: *cpu_type = "i386/ppro"; @@ -595,15 +621,19 @@ static int __init ppro_init(char **cpu_type) case 14: *cpu_type = "i386/core"; break; - case 15: case 23: + case 0x0f: + case 0x16: + case 0x17: + case 0x1d: *cpu_type = "i386/core_2"; break; + case 0x1a: + case 0x1e: case 0x2e: - case 26: spec = &op_arch_perfmon_spec; *cpu_type = "i386/core_i7"; break; - case 28: + case 0x1c: *cpu_type = "i386/atom"; break; default: @@ -625,6 +655,8 @@ int __init op_nmi_init(struct oprofile_operations *ops) char *cpu_type = NULL; int ret = 0; + using_nmi = 0; + if (!cpu_has_apic) return -ENODEV; @@ -707,7 +739,10 @@ int __init op_nmi_init(struct oprofile_operations *ops) mux_init(ops); - init_sysfs(); + ret = init_sysfs(); + if (ret) + return ret; + using_nmi = 1; printk(KERN_INFO "oprofile: using NMI interrupt.\n"); return 0; diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 39686c29f03a..1ed963d2e9b6 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -76,19 +76,6 @@ static struct op_ibs_config ibs_config; #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX -static void op_mux_fill_in_addresses(struct op_msrs * const msrs) -{ - int i; - - for (i = 0; i < NUM_VIRT_COUNTERS; i++) { - int hw_counter = op_x86_virt_to_phys(i); - if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) - msrs->multiplex[i].addr = MSR_K7_PERFCTR0 + hw_counter; - else - msrs->multiplex[i].addr = 0; - } -} - static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, struct op_msrs const * const msrs) { @@ -98,7 +85,7 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, /* enable active counters */ for (i = 0; i < NUM_COUNTERS; ++i) { int virt = op_x86_phys_to_virt(i); - if (!counter_config[virt].enabled) + if (!reset_value[virt]) continue; rdmsrl(msrs->controls[i].addr, val); val &= model->reserved; @@ -107,10 +94,6 @@ static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, } } -#else - -static inline void op_mux_fill_in_addresses(struct op_msrs * const msrs) { } - #endif /* functions for op_amd_spec */ @@ -122,18 +105,12 @@ static void op_amd_fill_in_addresses(struct op_msrs * const msrs) for (i = 0; i < NUM_COUNTERS; i++) { if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; - else - msrs->counters[i].addr = 0; } for (i = 0; i < NUM_CONTROLS; i++) { if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; - else - msrs->controls[i].addr = 0; } - - op_mux_fill_in_addresses(msrs); } static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, @@ -144,7 +121,8 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, /* setup reset_value */ for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { - if (counter_config[i].enabled) + if (counter_config[i].enabled + && msrs->counters[op_x86_virt_to_phys(i)].addr) reset_value[i] = counter_config[i].count; else reset_value[i] = 0; @@ -169,9 +147,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, /* enable active counters */ for (i = 0; i < NUM_COUNTERS; ++i) { int virt = op_x86_phys_to_virt(i); - if (!counter_config[virt].enabled) - continue; - if (!msrs->counters[i].addr) + if (!reset_value[virt]) continue; /* setup counter registers */ @@ -405,16 +381,6 @@ static int init_ibs_nmi(void) return 1; } -#ifdef CONFIG_NUMA - /* Sanity check */ - /* Works only for 64bit with proper numa implementation. */ - if (nodes != num_possible_nodes()) { - printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, " - "found: %d, expected %d", - nodes, num_possible_nodes()); - return 1; - } -#endif return 0; } diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index ac6b354becdf..e6a160a4684a 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c @@ -394,12 +394,6 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) setup_num_counters(); stag = get_stagger(); - /* initialize some registers */ - for (i = 0; i < num_counters; ++i) - msrs->counters[i].addr = 0; - for (i = 0; i < num_controls; ++i) - msrs->controls[i].addr = 0; - /* the counter & cccr registers we pay attention to */ for (i = 0; i < num_counters; ++i) { addr = p4_counters[VIRT_CTR(stag, i)].counter_address; diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index 8eb05878554c..2873c0087836 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -37,15 +37,11 @@ static void ppro_fill_in_addresses(struct op_msrs * const msrs) for (i = 0; i < num_counters; i++) { if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; - else - msrs->counters[i].addr = 0; } for (i = 0; i < num_counters; i++) { if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; - else - msrs->controls[i].addr = 0; } } @@ -57,7 +53,7 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, int i; if (!reset_value) { - reset_value = kmalloc(sizeof(reset_value[0]) * num_counters, + reset_value = kzalloc(sizeof(reset_value[0]) * num_counters, GFP_ATOMIC); if (!reset_value) return; diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 0696d506c4ad..b02f6d8ac922 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -590,6 +590,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH10_1: case PCI_DEVICE_ID_INTEL_ICH10_2: case PCI_DEVICE_ID_INTEL_ICH10_3: + case PCI_DEVICE_ID_INTEL_CPT_LPC1: + case PCI_DEVICE_ID_INTEL_CPT_LPC2: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 8aa85f17667e..fa0f651c573e 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -104,12 +104,15 @@ static void __save_processor_state(struct saved_context *ctxt) ctxt->cr4 = read_cr4(); ctxt->cr8 = read_cr8(); #endif + ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE, + &ctxt->misc_enable); } /* Needed by apm.c */ void save_processor_state(void) { __save_processor_state(&saved_context); + save_sched_clock_state(); } #ifdef CONFIG_X86_32 EXPORT_SYMBOL(save_processor_state); @@ -176,6 +179,8 @@ static void fix_processor_context(void) */ static void __restore_processor_state(struct saved_context *ctxt) { + if (ctxt->misc_enable_saved) + wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable); /* * control registers */ @@ -249,6 +254,7 @@ static void __restore_processor_state(struct saved_context *ctxt) void restore_processor_state(void) { __restore_processor_state(&saved_context); + restore_sched_clock_state(); } #ifdef CONFIG_X86_32 EXPORT_SYMBOL(restore_processor_state); diff --git a/arch/x86/power/hibernate_asm_32.S b/arch/x86/power/hibernate_asm_32.S index b641388d8286..ad47daeafa4e 100644 --- a/arch/x86/power/hibernate_asm_32.S +++ b/arch/x86/power/hibernate_asm_32.S @@ -27,10 +27,17 @@ ENTRY(swsusp_arch_suspend) ret ENTRY(restore_image) + movl mmu_cr4_features, %ecx movl resume_pg_dir, %eax subl $__PAGE_OFFSET, %eax movl %eax, %cr3 + jecxz 1f # cr4 Pentium and higher, skip if zero + andl $~(X86_CR4_PGE), %ecx + movl %ecx, %cr4; # turn off PGE + movl %cr3, %eax; # flush TLB + movl %eax, %cr3 +1: movl restore_pblist, %edx .p2align 4,,7 @@ -54,16 +61,8 @@ done: movl $swapper_pg_dir, %eax subl $__PAGE_OFFSET, %eax movl %eax, %cr3 - /* Flush TLB, including "global" things (vmalloc) */ movl mmu_cr4_features, %ecx jecxz 1f # cr4 Pentium and higher, skip if zero - movl %ecx, %edx - andl $~(X86_CR4_PGE), %edx - movl %edx, %cr4; # turn off PGE -1: - movl %cr3, %eax; # flush TLB - movl %eax, %cr3 - jecxz 1f # cr4 Pentium and higher, skip if zero movl %ecx, %cr4; # turn PGE back on 1: diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 79f97383cde3..0087b0098903 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -923,7 +924,7 @@ static const struct pv_init_ops xen_init_ops __initdata = { }; static const struct pv_time_ops xen_time_ops __initdata = { - .sched_clock = xen_sched_clock, + .sched_clock = xen_clocksource_read, }; static const struct pv_cpu_ops xen_cpu_ops __initdata = { @@ -996,10 +997,6 @@ static void xen_reboot(int reason) { struct sched_shutdown r = { .reason = reason }; -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r)) BUG(); } @@ -1092,6 +1089,12 @@ asmlinkage void __init xen_start_kernel(void) __supported_pte_mask |= _PAGE_IOMAP; + /* + * Prevent page tables from being allocated in highmem, even + * if CONFIG_HIGHPTE is enabled. + */ + __userpte_alloc_gfp &= ~__GFP_HIGHMEM; + #ifdef CONFIG_X86_64 /* Work out if we support NX */ check_efer(); diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index bf4cd6bfe959..350a3deedf25 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1432,14 +1432,15 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type) { pgprot_t prot = PAGE_KERNEL; + /* + * We disable highmem allocations for page tables so we should never + * see any calls to kmap_atomic_pte on a highmem page. + */ + BUG_ON(PageHighMem(page)); + if (PagePinned(page)) prot = PAGE_KERNEL_RO; - if (0 && PageHighMem(page)) - printk("mapping highpte %lx type %d prot %s\n", - page_to_pfn(page), type, - (unsigned long)pgprot_val(prot) & _PAGE_RW ? "WRITE" : "READ"); - return kmap_atomic_prot(page, type, prot); } #endif diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 360f8d8c19cd..ca5f56e9aaa0 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -396,9 +396,9 @@ static void stop_self(void *v) BUG(); } -static void xen_smp_send_stop(void) +static void xen_stop_other_cpus(int wait) { - smp_call_function(stop_self, NULL, 0); + smp_call_function(stop_self, NULL, wait); } static void xen_smp_send_reschedule(int cpu) @@ -466,7 +466,7 @@ static const struct smp_ops xen_smp_ops __initdata = { .cpu_disable = xen_cpu_disable, .play_dead = xen_play_dead, - .smp_send_stop = xen_smp_send_stop, + .stop_other_cpus = xen_stop_other_cpus, .smp_send_reschedule = xen_smp_send_reschedule, .send_call_func_ipi = xen_smp_send_call_function_ipi, diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index 987267f79bf5..a9c661108034 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c @@ -60,6 +60,6 @@ static void xen_vcpu_notify_restore(void *data) void xen_arch_resume(void) { - smp_call_function(xen_vcpu_notify_restore, - (void *)CLOCK_EVT_NOTIFY_RESUME, 1); + on_each_cpu(xen_vcpu_notify_restore, + (void *)CLOCK_EVT_NOTIFY_RESUME, 1); } diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 9d1f853120d8..8e04980d4697 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -154,45 +154,6 @@ static void do_stolen_accounting(void) account_idle_ticks(ticks); } -/* - * Xen sched_clock implementation. Returns the number of unstolen - * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED - * states. - */ -unsigned long long xen_sched_clock(void) -{ - struct vcpu_runstate_info state; - cycle_t now; - u64 ret; - s64 offset; - - /* - * Ideally sched_clock should be called on a per-cpu basis - * anyway, so preempt should already be disabled, but that's - * not current practice at the moment. - */ - preempt_disable(); - - now = xen_clocksource_read(); - - get_runstate_snapshot(&state); - - WARN_ON(state.state != RUNSTATE_running); - - offset = now - state.state_entry_time; - if (offset < 0) - offset = 0; - - ret = state.time[RUNSTATE_blocked] + - state.time[RUNSTATE_running] + - offset; - - preempt_enable(); - - return ret; -} - - /* Get the TSC speed from Xen */ unsigned long xen_tsc_khz(void) { diff --git a/arch/xtensa/include/asm/cache.h b/arch/xtensa/include/asm/cache.h index f04c9891142f..ed8cd3cbd499 100644 --- a/arch/xtensa/include/asm/cache.h +++ b/arch/xtensa/include/asm/cache.h @@ -29,5 +29,6 @@ # define CACHE_WAY_SIZE ICACHE_WAY_SIZE #endif +#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES #endif /* _XTENSA_CACHE_H */ diff --git a/block/blk-map.c b/block/blk-map.c index 9083cf0180cc..30a7e5158930 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -205,6 +205,8 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, unaligned = 1; break; } + if (!iov[i].iov_len) + return -EINVAL; } if (unaligned || (q->dma_pad_mask & len) || map_data) diff --git a/block/blk-settings.c b/block/blk-settings.c index d5aa8865c644..7c7b8c1c190f 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -8,6 +8,7 @@ #include #include /* for max_pfn/max_low_pfn */ #include +#include #include "blk.h" @@ -351,7 +352,7 @@ EXPORT_SYMBOL(blk_queue_logical_block_size); * hardware can operate on without reverting to read-modify-write * operations. */ -void blk_queue_physical_block_size(struct request_queue *q, unsigned short size) +void blk_queue_physical_block_size(struct request_queue *q, unsigned int size) { q->limits.physical_block_size = size; @@ -490,18 +491,31 @@ EXPORT_SYMBOL(blk_queue_stack_limits); /** * blk_stack_limits - adjust queue_limits for stacked devices - * @t: the stacking driver limits (top) - * @b: the underlying queue limits (bottom) + * @t: the stacking driver limits (top device) + * @b: the underlying queue limits (bottom, component device) * @offset: offset to beginning of data within component device * * Description: - * Merges two queue_limit structs. Returns 0 if alignment didn't - * change. Returns -1 if adding the bottom device caused - * misalignment. + * This function is used by stacking drivers like MD and DM to ensure + * that all component devices have compatible block sizes and + * alignments. The stacking driver must provide a queue_limits + * struct (top) and then iteratively call the stacking function for + * all component (bottom) devices. The stacking function will + * attempt to combine the values and ensure proper alignment. + * + * Returns 0 if the top and bottom queue_limits are compatible. The + * top device's block sizes and alignment offsets may be adjusted to + * ensure alignment with the bottom device. If no compatible sizes + * and alignments exist, -1 is returned and the resulting top + * queue_limits will have the misaligned flag set to indicate that + * the alignment_offset is undefined. */ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, sector_t offset) { + sector_t alignment; + unsigned int top, bottom, ret = 0; + t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn); @@ -518,6 +532,26 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, t->max_segment_size = min_not_zero(t->max_segment_size, b->max_segment_size); + t->misaligned |= b->misaligned; + + alignment = queue_limit_alignment_offset(b, offset); + + /* Bottom device has different alignment. Check that it is + * compatible with the current top alignment. + */ + if (t->alignment_offset != alignment) { + + top = max(t->physical_block_size, t->io_min) + + t->alignment_offset; + bottom = max(b->physical_block_size, b->io_min) + alignment; + + /* Verify that top and bottom intervals line up */ + if (max(top, bottom) & (min(top, bottom) - 1)) { + t->misaligned = 1; + ret = -1; + } + } + t->logical_block_size = max(t->logical_block_size, b->logical_block_size); @@ -525,37 +559,46 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, b->physical_block_size); t->io_min = max(t->io_min, b->io_min); + t->io_opt = lcm(t->io_opt, b->io_opt); + t->no_cluster |= b->no_cluster; - /* Bottom device offset aligned? */ - if (offset && - (offset & (b->physical_block_size - 1)) != b->alignment_offset) { + /* Physical block size a multiple of the logical block size? */ + if (t->physical_block_size & (t->logical_block_size - 1)) { + t->physical_block_size = t->logical_block_size; t->misaligned = 1; - return -1; + ret = -1; } - /* If top has no alignment offset, inherit from bottom */ - if (!t->alignment_offset) - t->alignment_offset = - b->alignment_offset & (b->physical_block_size - 1); + /* Minimum I/O a multiple of the physical block size? */ + if (t->io_min & (t->physical_block_size - 1)) { + t->io_min = t->physical_block_size; + t->misaligned = 1; + ret = -1; + } - /* Top device aligned on logical block boundary? */ + /* Optimal I/O a multiple of the physical block size? */ + if (t->io_opt & (t->physical_block_size - 1)) { + t->io_opt = 0; + t->misaligned = 1; + ret = -1; + } + + /* Find lowest common alignment_offset */ + t->alignment_offset = lcm(t->alignment_offset, alignment) + & (max(t->physical_block_size, t->io_min) - 1); + + /* Verify that new alignment_offset is on a logical block boundary */ if (t->alignment_offset & (t->logical_block_size - 1)) { t->misaligned = 1; - return -1; + ret = -1; } - /* Find lcm() of optimal I/O size */ - if (t->io_opt && b->io_opt) - t->io_opt = (t->io_opt * b->io_opt) / gcd(t->io_opt, b->io_opt); - else if (b->io_opt) - t->io_opt = b->io_opt; + /* Discard */ + t->max_discard_sectors = min_not_zero(t->max_discard_sectors, + b->max_discard_sectors); - /* Verify that optimal I/O size is a multiple of io_min */ - if (t->io_min && t->io_opt % t->io_min) - return -1; - - return 0; + return ret; } EXPORT_SYMBOL(blk_stack_limits); diff --git a/block/blk-timeout.c b/block/blk-timeout.c index 1ba7e0aca878..4f0c06c7a338 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c @@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned long data) struct request_queue *q = (struct request_queue *) data; unsigned long flags, next = 0; struct request *rq, *tmp; + int next_set = 0; spin_lock_irqsave(q->queue_lock, flags); @@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned long data) if (blk_mark_rq_complete(rq)) continue; blk_rq_timed_out(rq); - } else if (!next || time_after(next, rq->deadline)) + } else if (!next_set || time_after(next, rq->deadline)) { next = rq->deadline; + next_set = 1; + } } - /* - * next can never be 0 here with the list non-empty, since we always - * bump ->deadline to 1 so we can detect if the timer was ever added - * or not. See comment in blk_add_timer() - */ - if (next) + if (next_set) mod_timer(&q->timeout, round_jiffies_up(next)); spin_unlock_irqrestore(q->queue_lock, flags); diff --git a/block/bsg.c b/block/bsg.c index 0676301f16d0..7154a7a7e9ca 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -424,7 +424,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, /* * fill in all the output members */ - hdr->device_status = status_byte(rq->errors); + hdr->device_status = rq->errors & 0xff; hdr->transport_status = host_byte(rq->errors); hdr->driver_status = driver_byte(rq->errors); hdr->info = 0; diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index e5b10017a50b..1d5a7805446b 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -319,33 +319,47 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->iovec_count) { const int size = sizeof(struct sg_iovec) * hdr->iovec_count; size_t iov_data_len; - struct sg_iovec *iov; + struct sg_iovec *sg_iov; + struct iovec *iov; + int i; - iov = kmalloc(size, GFP_KERNEL); - if (!iov) { + sg_iov = kmalloc(size, GFP_KERNEL); + if (!sg_iov) { ret = -ENOMEM; goto out; } - if (copy_from_user(iov, hdr->dxferp, size)) { - kfree(iov); + if (copy_from_user(sg_iov, hdr->dxferp, size)) { + kfree(sg_iov); ret = -EFAULT; goto out; } + /* + * Sum up the vecs, making sure they don't overflow + */ + iov = (struct iovec *) sg_iov; + iov_data_len = 0; + for (i = 0; i < hdr->iovec_count; i++) { + if (iov_data_len + iov[i].iov_len < iov_data_len) { + kfree(sg_iov); + ret = -EINVAL; + goto out; + } + iov_data_len += iov[i].iov_len; + } + /* SG_IO howto says that the shorter of the two wins */ - iov_data_len = iov_length((struct iovec *)iov, - hdr->iovec_count); if (hdr->dxfer_len < iov_data_len) { - hdr->iovec_count = iov_shorten((struct iovec *)iov, + hdr->iovec_count = iov_shorten(iov, hdr->iovec_count, hdr->dxfer_len); iov_data_len = hdr->dxfer_len; } - ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, + ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count, iov_data_len, GFP_KERNEL); - kfree(iov); + kfree(sg_iov); } else if (hdr->dxfer_len) ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, GFP_KERNEL); diff --git a/crypto/async_tx/async_raid6_recov.c b/crypto/async_tx/async_raid6_recov.c index 943f2abac9b4..ce038d861eb9 100644 --- a/crypto/async_tx/async_raid6_recov.c +++ b/crypto/async_tx/async_raid6_recov.c @@ -324,6 +324,7 @@ struct dma_async_tx_descriptor * async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb, struct page **blocks, struct async_submit_ctl *submit) { + void *scribble = submit->scribble; int non_zero_srcs, i; BUG_ON(faila == failb); @@ -332,11 +333,13 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb, pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes); - /* we need to preserve the contents of 'blocks' for the async - * case, so punt to synchronous if a scribble buffer is not available + /* if a dma resource is not available or a scribble buffer is not + * available punt to the synchronous path. In the 'dma not + * available' case be sure to use the scribble buffer to + * preserve the content of 'blocks' as the caller intended. */ - if (!submit->scribble) { - void **ptrs = (void **) blocks; + if (!async_dma_find_channel(DMA_PQ) || !scribble) { + void **ptrs = scribble ? scribble : (void **) blocks; async_tx_quiesce(&submit->depend_tx); for (i = 0; i < disks; i++) @@ -406,11 +409,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila, pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes); - /* we need to preserve the contents of 'blocks' for the async - * case, so punt to synchronous if a scribble buffer is not available + /* if a dma resource is not available or a scribble buffer is not + * available punt to the synchronous path. In the 'dma not + * available' case be sure to use the scribble buffer to + * preserve the content of 'blocks' as the caller intended. */ - if (!scribble) { - void **ptrs = (void **) blocks; + if (!async_dma_find_channel(DMA_PQ) || !scribble) { + void **ptrs = scribble ? scribble : (void **) blocks; async_tx_quiesce(&submit->depend_tx); for (i = 0; i < disks; i++) diff --git a/crypto/authenc.c b/crypto/authenc.c index 4d6f49a5daeb..0d54de911050 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -46,6 +46,12 @@ struct authenc_request_ctx { char tail[]; }; +static void authenc_request_complete(struct aead_request *req, int err) +{ + if (err != -EINPROGRESS) + aead_request_complete(req, err); +} + static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, unsigned int keylen) { @@ -142,7 +148,7 @@ static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq, crypto_aead_authsize(authenc), 1); out: - aead_request_complete(req, err); + authenc_request_complete(req, err); } static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err) @@ -208,7 +214,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq, err = crypto_ablkcipher_decrypt(abreq); out: - aead_request_complete(req, err); + authenc_request_complete(req, err); } static void authenc_verify_ahash_done(struct crypto_async_request *areq, @@ -245,7 +251,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq, err = crypto_ablkcipher_decrypt(abreq); out: - aead_request_complete(req, err); + authenc_request_complete(req, err); } static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags) @@ -379,7 +385,7 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req, err = crypto_authenc_genicv(areq, iv, 0); } - aead_request_complete(areq, err); + authenc_request_complete(areq, err); } static int crypto_authenc_encrypt(struct aead_request *req) @@ -418,7 +424,7 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req, err = crypto_authenc_genicv(areq, greq->giv, 0); } - aead_request_complete(areq, err); + authenc_request_complete(areq, err); } static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 6d5b746637be..2a4106d37946 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1477,9 +1477,54 @@ static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, return err; } +static int alg_test_null(const struct alg_test_desc *desc, + const char *driver, u32 type, u32 mask) +{ + return 0; +} + /* Please keep this list sorted by algorithm name. */ static const struct alg_test_desc alg_test_descs[] = { { + .alg = "__driver-cbc-aes-aesni", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { + .alg = "__driver-ecb-aes-aesni", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { + .alg = "__ghash-pclmulqdqni", + .test = alg_test_null, + .suite = { + .hash = { + .vecs = NULL, + .count = 0 + } + } + }, { .alg = "ansi_cprng", .test = alg_test_cprng, .fips_allowed = 1, @@ -1622,6 +1667,30 @@ static const struct alg_test_desc alg_test_descs[] = { .count = CRC32C_TEST_VECTORS } } + }, { + .alg = "cryptd(__driver-ecb-aes-aesni)", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } + }, { + .alg = "cryptd(__ghash-pclmulqdqni)", + .test = alg_test_null, + .suite = { + .hash = { + .vecs = NULL, + .count = 0 + } + } }, { .alg = "ctr(aes)", .test = alg_test_skcipher, @@ -1668,6 +1737,21 @@ static const struct alg_test_desc alg_test_descs[] = { } } } + }, { + .alg = "ecb(__aes-aesni)", + .test = alg_test_null, + .suite = { + .cipher = { + .enc = { + .vecs = NULL, + .count = 0 + }, + .dec = { + .vecs = NULL, + .count = 0 + } + } + } }, { .alg = "ecb(aes)", .test = alg_test_skcipher, diff --git a/drivers/Makefile b/drivers/Makefile index 73020396902a..68548675116c 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_SFI) += sfi/ obj-$(CONFIG_PNP) += pnp/ obj-$(CONFIG_ARM_AMBA) += amba/ +obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_XEN) += xen/ # regulators early, since some subsystems rely on them to initialize @@ -109,7 +110,6 @@ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ -obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 81e64f478679..d46e2565ae47 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -846,6 +846,7 @@ struct acpi_bit_register_info { ACPI_BITMASK_POWER_BUTTON_STATUS | \ ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ ACPI_BITMASK_RT_CLOCK_STATUS | \ + ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ ACPI_BITMASK_WAKE_STATUS) #define ACPI_BITMASK_TIMER_ENABLE 0x0001 diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 52fec07064f0..83b62521d8d3 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -468,6 +468,23 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_ut_add_reference(obj_desc->field.region_obj); + /* allow full data read from EC address space */ + if (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_EC) { + if (obj_desc->common_field.bit_length > 8) { + unsigned width = + ACPI_ROUND_BITS_UP_TO_BYTES( + obj_desc->common_field.bit_length); + // access_bit_width is u8, don't overflow it + if (width > 8) + width = 8; + obj_desc->common_field.access_byte_width = + width; + obj_desc->common_field.access_bit_width = + 8 * width; + } + } + ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", obj_desc->field.start_field_bit_offset, diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 23e5a0519af5..5624d7bc24af 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -185,6 +185,12 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) acpi_osi_setup("!Windows 2006"); return 0; } +static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) +{ + printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); + acpi_osi_setup("!Windows 2009"); + return 0; +} static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { { @@ -211,6 +217,38 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), }, }, + { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba Satellite L355", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba Satellite L355", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), + }, + }, + { + .callback = dmi_disable_osi_win7, + .ident = "ASUS K50IJ", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), + }, + }, + { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba P305D", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), + }, + }, /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f1670e0ef9bb..45d2aa93258e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -588,12 +588,12 @@ static u32 acpi_ec_gpe_handler(void *data) static acpi_status acpi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, acpi_integer *value, + u32 bits, acpi_integer *value64, void *handler_context, void *region_context) { struct acpi_ec *ec = handler_context; - int result = 0, i; - u8 temp = 0; + int result = 0, i, bytes = bits / 8; + u8 *value = (u8 *)value64; if ((address > 0xFF) || !value || !handler_context) return AE_BAD_PARAMETER; @@ -601,32 +601,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, if (function != ACPI_READ && function != ACPI_WRITE) return AE_BAD_PARAMETER; - if (bits != 8 && acpi_strict) - return AE_BAD_PARAMETER; - - if (EC_FLAGS_MSI) + if (EC_FLAGS_MSI || bits > 8) acpi_ec_burst_enable(ec); - if (function == ACPI_READ) { - result = acpi_ec_read(ec, address, &temp); - *value = temp; - } else { - temp = 0xff & (*value); - result = acpi_ec_write(ec, address, temp); - } + for (i = 0; i < bytes; ++i, ++address, ++value) + result = (function == ACPI_READ) ? + acpi_ec_read(ec, address, value) : + acpi_ec_write(ec, address, *value); - for (i = 8; unlikely(bits - i > 0); i += 8) { - ++address; - if (function == ACPI_READ) { - result = acpi_ec_read(ec, address, &temp); - (*value) |= ((acpi_integer)temp) << i; - } else { - temp = 0xff & ((*value) >> i); - result = acpi_ec_write(ec, address, temp); - } - } - - if (EC_FLAGS_MSI) + if (EC_FLAGS_MSI || bits > 8) acpi_ec_burst_disable(ec); switch (result) { diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c index 2ef7030a0c28..c21606261318 100644 --- a/drivers/acpi/power_meter.c +++ b/drivers/acpi/power_meter.c @@ -34,7 +34,7 @@ #define ACPI_POWER_METER_NAME "power_meter" ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); #define ACPI_POWER_METER_DEVICE_NAME "Power Meter" -#define ACPI_POWER_METER_CLASS "power_meter_resource" +#define ACPI_POWER_METER_CLASS "pwr_meter_resource" #define NUM_SENSORS 17 diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index ec742a4e5635..71024740d62b 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -133,12 +133,6 @@ static int set_no_mwait(const struct dmi_system_id *id) } static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { - { - set_no_mwait, "IFL91 board", { - DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), - DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), - DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, { set_no_mwait, "Extensa 5220", { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index d9f78f6cbda3..a6ad608c96a2 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -888,12 +888,14 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, return(acpi_idle_enter_c1(dev, state)); local_irq_disable(); - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); + if (cx->entry_method != ACPI_CSTATE_FFH) { + current_thread_info()->status &= ~TS_POLLING; + /* + * TS_POLLING-cleared state must be visible before we test + * NEED_RESCHED: + */ + smp_mb(); + } if (unlikely(need_resched())) { current_thread_info()->status |= TS_POLLING; @@ -960,7 +962,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, if (acpi_idle_suspend) return(acpi_idle_enter_c1(dev, state)); - if (acpi_idle_bm_check()) { + if (!cx->bm_sts_skip && acpi_idle_bm_check()) { if (dev->safe_state) { dev->last_state = dev->safe_state; return dev->safe_state->enter(dev, dev->safe_state); @@ -973,12 +975,14 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, } local_irq_disable(); - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); + if (cx->entry_method != ACPI_CSTATE_FFH) { + current_thread_info()->status &= ~TS_POLLING; + /* + * TS_POLLING-cleared state must be visible before we test + * NEED_RESCHED: + */ + smp_mb(); + } if (unlikely(need_resched())) { current_thread_info()->status |= TS_POLLING; diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 8ba0ed0b9ddb..40d395efec1e 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -356,7 +356,11 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) if (result) goto update_bios; - return 0; + /* We need to call _PPC once when cpufreq starts */ + if (ignore_ppc != 1) + result = acpi_processor_get_platform_limit(pr); + + return result; /* * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5f2c379ab7bf..045809465347 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -80,6 +80,7 @@ static int acpi_sleep_prepare(u32 acpi_state) #ifdef CONFIG_ACPI_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; + /* * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the * user to request that behavior by using the 'acpi_old_suspend_ordering' @@ -170,18 +171,6 @@ static void acpi_pm_end(void) #endif /* CONFIG_ACPI_SLEEP */ #ifdef CONFIG_SUSPEND -/* - * According to the ACPI specification the BIOS should make sure that ACPI is - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI - * on such systems during resume. Unfortunately that doesn't help in - * particularly pathological cases in which SCI_EN has to be set directly on - * resume, although the specification states very clearly that this flag is - * owned by the hardware. The set_sci_en_on_resume variable will be set in such - * cases. - */ -static bool set_sci_en_on_resume; - extern void do_suspend_lowlevel(void); static u32 acpi_suspend_states[] = { @@ -248,11 +237,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) break; } - /* If ACPI is not enabled by the BIOS, we need to enable it here. */ - if (set_sci_en_on_resume) - acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); - else - acpi_enable(); + /* This violates the spec but is required for bug compatibility. */ + acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); /* Reprogram control registers and execute _BFS */ acpi_leave_sleep_state_prep(acpi_state); @@ -341,12 +327,6 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) return 0; } -static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) -{ - set_sci_en_on_resume = true; - return 0; -} - static struct dmi_system_id __initdata acpisleep_dmi_table[] = { { .callback = init_old_suspend_ordering, @@ -365,22 +345,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, }, { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacBook 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacMini 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), - }, - }, - { .callback = init_old_suspend_ordering, .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", .matches = { @@ -389,62 +353,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, }, { - .callback = init_set_sci_en_on_resume, - .ident = "Toshiba Satellite L300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard HP G7000 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP G7000 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard HP Pavilion dv3 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv3 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Pavilion dv4", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Pavilion dv7", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario CQ40 Notebook PC"), - }, - }, - { .callback = init_old_suspend_ordering, .ident = "Panasonic CF51-2L", .matches = { diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index f336bca7c450..8a0ed2800e63 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -213,7 +213,7 @@ acpi_table_parse_entries(char *id, unsigned long table_end; acpi_size tbl_size; - if (acpi_disabled) + if (acpi_disabled && !acpi_ht) return -ENODEV; if (!handler) @@ -280,7 +280,7 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) struct acpi_table_header *table = NULL; acpi_size tbl_size; - if (acpi_disabled) + if (acpi_disabled && !acpi_ht) return -ENODEV; if (!handler) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 575593a8b4e6..e7b960602b66 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -250,7 +250,7 @@ static int __init acpi_backlight(char *str) ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; if (!strcmp("video", str)) acpi_video_support |= - ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; + ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO; } return 1; } diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 9b375028318a..e3d9816b2a22 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -570,6 +570,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ + { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ + { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ + { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -2831,6 +2837,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) * On HP dv[4-6] and HDX18 with earlier BIOSen, link * to the harddisk doesn't become online after * resuming from STR. Warn and fail suspend. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=12276 + * + * Use dates instead of versions to match as HP is + * apparently recycling both product and version + * strings. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=15462 */ { .ident = "dv4", @@ -2839,7 +2853,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), }, - .driver_data = "F.30", /* cutoff BIOS version */ + .driver_data = "20090105", /* F.30 */ }, { .ident = "dv5", @@ -2848,7 +2862,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv5 Notebook PC"), }, - .driver_data = "F.16", /* cutoff BIOS version */ + .driver_data = "20090506", /* F.16 */ }, { .ident = "dv6", @@ -2857,7 +2871,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6 Notebook PC"), }, - .driver_data = "F.21", /* cutoff BIOS version */ + .driver_data = "20090423", /* F.21 */ }, { .ident = "HDX18", @@ -2866,7 +2880,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP HDX18 Notebook PC"), }, - .driver_data = "F.23", /* cutoff BIOS version */ + .driver_data = "20090430", /* F.23 */ }, /* * Acer eMachines G725 has the same problem. BIOS @@ -2874,6 +2888,8 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) * work. Inbetween, there are V1.06, V2.06 and V3.03 * that we don't have much idea about. For now, * blacklist anything older than V3.04. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=15104 */ { .ident = "G725", @@ -2881,19 +2897,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), }, - .driver_data = "V3.04", /* cutoff BIOS version */ + .driver_data = "20091216", /* V3.04 */ }, { } /* terminate list */ }; const struct dmi_system_id *dmi = dmi_first_match(sysids); - const char *ver; + int year, month, date; + char buf[9]; if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) return false; - ver = dmi_get_system_info(DMI_BIOS_VERSION); + dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); + snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); - return !ver || strcmp(ver, dmi->driver_data) < 0; + return strcmp(buf, dmi->driver_data) < 0; } static bool ahci_broken_online(struct pci_dev *pdev) @@ -3019,6 +3037,16 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable) return -ENODEV; + /* + * For some reason, MCP89 on MacBook 7,1 doesn't work with + * ahci, use ata_generic instead. + */ + if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && + pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA && + pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE && + pdev->subsystem_device == 0xcb89) + return -ENODEV; + /* acquire resources */ rc = pcim_enable_device(pdev); if (rc) @@ -3074,8 +3102,16 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ahci_save_initial_config(pdev, hpriv); /* prepare host */ - if (hpriv->cap & HOST_CAP_NCQ) - pi.flags |= ATA_FLAG_NCQ | ATA_FLAG_FPDMA_AA; + if (hpriv->cap & HOST_CAP_NCQ) { + pi.flags |= ATA_FLAG_NCQ; + /* Auto-activate optimization is supposed to be supported on + all AHCI controllers indicating NCQ support, but it seems + to be broken at least on some NVIDIA MCP79 chipsets. + Until we get info on which NVIDIA chipsets don't have this + issue, if any, disable AA on all NVIDIA AHCIs. */ + if (pdev->vendor != PCI_VENDOR_ID_NVIDIA) + pi.flags |= ATA_FLAG_FPDMA_AA; + } if (hpriv->cap & HOST_CAP_PMP) pi.flags |= ATA_FLAG_PMP; diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index ecfd22b4f1ce..99e719619e7d 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -32,6 +32,11 @@ * A generic parallel ATA driver using libata */ +enum { + ATA_GEN_CLASS_MATCH = (1 << 0), + ATA_GEN_FORCE_DMA = (1 << 1), +}; + /** * generic_set_mode - mode setting * @link: link to set up @@ -46,13 +51,17 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused) { struct ata_port *ap = link->ap; + const struct pci_device_id *id = ap->host->private_data; int dma_enabled = 0; struct ata_device *dev; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - /* Bits 5 and 6 indicate if DMA is active on master/slave */ - if (ap->ioaddr.bmdma_addr) + if (id->driver_data & ATA_GEN_FORCE_DMA) { + dma_enabled = 0xff; + } else if (ap->ioaddr.bmdma_addr) { + /* Bits 5 and 6 indicate if DMA is active on master/slave */ dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); + } if (pdev->vendor == PCI_VENDOR_ID_CENATEK) dma_enabled = 0xFF; @@ -126,7 +135,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id const struct ata_port_info *ppi[] = { &info, NULL }; /* Don't use the generic entry unless instructed to do so */ - if (id->driver_data == 1 && all_generic_ide == 0) + if ((id->driver_data & ATA_GEN_CLASS_MATCH) && all_generic_ide == 0) return -ENODEV; /* Devices that need care */ @@ -155,7 +164,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id return rc; pcim_pin_device(dev); } - return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL); + return ata_pci_sff_init_one(dev, ppi, &generic_sht, (void *)id); } static struct pci_device_id ata_generic[] = { @@ -167,12 +176,21 @@ static struct pci_device_id ata_generic[] = { { PCI_DEVICE(PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE), }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561), }, { PCI_DEVICE(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558), }, - { PCI_DEVICE(PCI_VENDOR_ID_CENATEK,PCI_DEVICE_ID_CENATEK_IDE), }, + { PCI_DEVICE(PCI_VENDOR_ID_CENATEK,PCI_DEVICE_ID_CENATEK_IDE), + .driver_data = ATA_GEN_FORCE_DMA }, + /* + * For some reason, MCP89 on MacBook 7,1 doesn't work with + * ahci, use ata_generic instead. + */ + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA, + PCI_VENDOR_ID_APPLE, 0xcb89, + .driver_data = ATA_GEN_FORCE_DMA }, { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO), }, { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), }, { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), }, /* Must come last. If you add entries adjust this table appropriately */ - { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1}, + { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL), + .driver_data = ATA_GEN_CLASS_MATCH }, { 0, }, }; diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 0c6155f51173..c33591d3a599 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -157,6 +157,7 @@ struct piix_map_db { struct piix_host_priv { const int *map; u32 saved_iocfg; + spinlock_t sidpr_lock; /* FIXME: remove once locking in EH is fixed */ void __iomem *sidpr; }; @@ -291,6 +292,14 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (PCH) */ { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (CPT) */ + { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ }; @@ -940,12 +949,15 @@ static int piix_sidpr_scr_read(struct ata_link *link, unsigned int reg, u32 *val) { struct piix_host_priv *hpriv = link->ap->host->private_data; + unsigned long flags; if (reg >= ARRAY_SIZE(piix_sidx_map)) return -EINVAL; + spin_lock_irqsave(&hpriv->sidpr_lock, flags); piix_sidpr_sel(link, reg); *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA); + spin_unlock_irqrestore(&hpriv->sidpr_lock, flags); return 0; } @@ -953,12 +965,15 @@ static int piix_sidpr_scr_write(struct ata_link *link, unsigned int reg, u32 val) { struct piix_host_priv *hpriv = link->ap->host->private_data; + unsigned long flags; if (reg >= ARRAY_SIZE(piix_sidx_map)) return -EINVAL; + spin_lock_irqsave(&hpriv->sidpr_lock, flags); piix_sidpr_sel(link, reg); iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA); + spin_unlock_irqrestore(&hpriv->sidpr_lock, flags); return 0; } @@ -1547,6 +1562,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) return -ENOMEM; + spin_lock_init(&hpriv->sidpr_lock); /* Save IOCFG, this will be used for cable detection, quirk * detection and restoration on detach. This is necessary diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 91fed3c93d66..0963cd6a1425 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -159,6 +159,10 @@ int libata_allow_tpm = 0; module_param_named(allow_tpm, libata_allow_tpm, int, 0444); MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands (0=off [default], 1=on)"); +static int atapi_an; +module_param(atapi_an, int, 0444); +MODULE_PARM_DESC(atapi_an, "Enable ATAPI AN media presence notification (0=0ff [default], 1=on)"); + MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); @@ -2570,7 +2574,8 @@ int ata_dev_configure(struct ata_device *dev) * to enable ATAPI AN to discern between PHY status * changed notifications and ATAPI ANs. */ - if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && + if (atapi_an && + (ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && (!sata_pmp_attached(ap) || sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { unsigned int err_mask; @@ -4348,6 +4353,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, + /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ + { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, }, + /* devices which puke on READ_NATIVE_MAX */ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA }, @@ -5496,6 +5504,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, */ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) { + unsigned int ehi_flags = ATA_EHI_QUIET; int rc; /* @@ -5504,7 +5513,18 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) */ ata_lpm_enable(host); - rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); + /* + * On some hardware, device fails to respond after spun down + * for suspend. As the device won't be used before being + * resumed, we don't need to touch the device. Ask EH to skip + * the usual stuff and proceed directly to suspend. + * + * http://thread.gmane.org/gmane.linux.ide/46764 + */ + if (mesg.event == PM_EVENT_SUSPEND) + ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY; + + rc = ata_host_request_pm(host, mesg, 0, ehi_flags, 1); if (rc == 0) host->dev->power.power_state = mesg; return rc; diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 7d8d3c3b4c80..fa9bed06b397 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -870,6 +870,8 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain) void ata_qc_schedule_eh(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; + struct request_queue *q = qc->scsicmd->device->request_queue; + unsigned long flags; WARN_ON(!ap->ops->error_handler); @@ -881,7 +883,9 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) * Note that ATA_QCFLAG_FAILED is unconditionally set after * this function completes. */ + spin_lock_irqsave(q->queue_lock, flags); blk_abort_request(qc->scsicmd->request); + spin_unlock_irqrestore(q->queue_lock, flags); } /** @@ -1615,6 +1619,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) } /* okay, this error is ours */ + memset(&tf, 0, sizeof(tf)); rc = ata_eh_read_log_10h(dev, &tag, &tf); if (rc) { ata_link_printk(link, KERN_ERR, "failed to read log page 10h " @@ -3144,6 +3149,10 @@ static int ata_eh_skip_recovery(struct ata_link *link) if (link->flags & ATA_LFLAG_DISABLED) return 1; + /* skip if explicitly requested */ + if (ehc->i.flags & ATA_EHI_NO_RECOVERY) + return 1; + /* thaw frozen port and recover failed devices */ if ((ap->pflags & ATA_PFLAG_FROZEN) || ata_link_nr_enabled(link)) return 0; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b4ee28dec521..a158a6c925d0 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2497,8 +2497,11 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) * * If door lock fails, always clear sdev->locked to * avoid this infinite loop. + * + * This may happen before SCSI scan is complete. Make + * sure qc->dev->sdev isn't NULL before dereferencing. */ - if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL) + if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev) qc->dev->sdev->locked = 0; qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; @@ -2825,7 +2828,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * write indication (used for PIO/DMA setup), result TF is * copied back and we don't whine too much about its failure. */ - tf->flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; if (scmd->sc_data_direction == DMA_TO_DEVICE) tf->flags |= ATA_TFLAG_WRITE; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 2ae15c3b22a7..776a89599448 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -893,7 +893,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) do_write); } - if (!do_write) + if (!do_write && !PageSlab(page)) flush_dcache_page(page); qc->curbytes += qc->sect_size; diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 1432dc9d0ab8..9434114b2ca8 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -453,7 +453,9 @@ static void ali_init_chipset(struct pci_dev *pdev) /* Clear CD-ROM DMA write bit */ tmp &= 0x7F; /* Cable and UDMA */ - pci_write_config_byte(pdev, 0x4B, tmp | 0x09); + if (pdev->revision >= 0xc2) + tmp |= 0x01; + pci_write_config_byte(pdev, 0x4B, tmp | 0x08); /* * CD_ROM DMA on (0x53 bit 0). Enable this even if we want * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index d16e87e29189..d9f2913f159b 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.8" +#define DRV_VERSION "0.3.9" enum { HPT_PCI_FAST = (1 << 31), @@ -547,16 +547,16 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_mhz); /* Set our private data up. We only need a few flags so we use it directly */ - if (pci_mhz > 60) { + if (pci_mhz > 60) hpriv = (void *)(PCI66 | USE_DPLL); - /* - * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in - * the MISC. register to stretch the UltraDMA Tss timing. - * NOTE: This register is only writeable via I/O space. - */ - if (dev->device == PCI_DEVICE_ID_TTI_HPT371) - outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); - } + + /* + * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in + * the MISC. register to stretch the UltraDMA Tss timing. + * NOTE: This register is only writeable via I/O space. + */ + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) + outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); /* Now kick off ATA set up */ return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv); diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index 2f3c9bed63d9..29111205185a 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -2,7 +2,7 @@ * pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox - * (C) 2007,2009 Bartlomiej Zolnierkiewicz + * (C) 2007,2009,2010 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/pdc202xx_old.c * @@ -35,6 +35,15 @@ static int pdc2026x_cable_detect(struct ata_port *ap) return ATA_CBL_PATA80; } +static void pdc202xx_exec_command(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); + + iowrite8(tf->command, ap->ioaddr.command_addr); + ndelay(400); +} + /** * pdc202xx_configure_piomode - set chip PIO timing * @ap: ATA interface @@ -271,6 +280,8 @@ static struct ata_port_operations pdc2024x_port_ops = { .cable_detect = ata_cable_40wire, .set_piomode = pdc202xx_set_piomode, .set_dmamode = pdc202xx_set_dmamode, + + .sff_exec_command = pdc202xx_exec_command, }; static struct ata_port_operations pdc2026x_port_ops = { @@ -284,6 +295,8 @@ static struct ata_port_operations pdc2026x_port_ops = { .dev_config = pdc2026x_dev_config, .port_start = pdc2026x_port_start, + + .sff_exec_command = pdc202xx_exec_command, }; static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 88984b803d6d..1d73b8d236ed 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -661,6 +661,7 @@ static const struct pci_device_id via[] = { { PCI_VDEVICE(VIA, 0x3164), }, { PCI_VDEVICE(VIA, 0x5324), }, { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE }, + { PCI_VDEVICE(VIA, 0x9001), VIA_IDFLAG_SINGLE }, { }, }; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 6f5093b7c8c5..cf41126ff426 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1879,19 +1879,25 @@ static void mv_bmdma_start(struct ata_queued_cmd *qc) * LOCKING: * Inherited from caller. */ -static void mv_bmdma_stop(struct ata_queued_cmd *qc) +static void mv_bmdma_stop_ap(struct ata_port *ap) { - struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); u32 cmd; /* clear start/stop bit */ cmd = readl(port_mmio + BMDMA_CMD); - cmd &= ~ATA_DMA_START; - writelfl(cmd, port_mmio + BMDMA_CMD); + if (cmd & ATA_DMA_START) { + cmd &= ~ATA_DMA_START; + writelfl(cmd, port_mmio + BMDMA_CMD); - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_sff_dma_pause(ap); + /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ + ata_sff_dma_pause(ap); + } +} + +static void mv_bmdma_stop(struct ata_queued_cmd *qc) +{ + mv_bmdma_stop_ap(qc->ap); } /** @@ -1915,8 +1921,21 @@ static u8 mv_bmdma_status(struct ata_port *ap) reg = readl(port_mmio + BMDMA_STATUS); if (reg & ATA_DMA_ACTIVE) status = ATA_DMA_ACTIVE; - else + else if (reg & ATA_DMA_ERR) status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; + else { + /* + * Just because DMA_ACTIVE is 0 (DMA completed), + * this does _not_ mean the device is "done". + * So we should not yet be signalling ATA_DMA_INTR + * in some cases. Eg. DSM/TRIM, and perhaps others. + */ + mv_bmdma_stop_ap(ap); + if (ioread8(ap->ioaddr.altstatus_addr) & ATA_BUSY) + status = 0; + else + status = ATA_DMA_INTR; + } return status; } @@ -1976,6 +1995,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) switch (tf->protocol) { case ATA_PROT_DMA: + if (tf->command == ATA_CMD_DSM) + return; + /* fall-thru */ case ATA_PROT_NCQ: break; /* continue below */ case ATA_PROT_PIO: @@ -2075,6 +2097,8 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) if ((tf->protocol != ATA_PROT_DMA) && (tf->protocol != ATA_PROT_NCQ)) return; + if (tf->command == ATA_CMD_DSM) + return; /* use bmdma for this */ /* Fill in Gen IIE command request block */ if (!(tf->flags & ATA_TFLAG_WRITE)) @@ -2270,6 +2294,12 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) switch (qc->tf.protocol) { case ATA_PROT_DMA: + if (qc->tf.command == ATA_CMD_DSM) { + if (!ap->ops->bmdma_setup) /* no bmdma on GEN_I */ + return AC_ERR_OTHER; + break; /* use bmdma for this */ + } + /* fall thru */ case ATA_PROT_NCQ: mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 1eb4e020eb5c..ae2297cd29d8 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1673,7 +1673,6 @@ static void nv_mcp55_freeze(struct ata_port *ap) mask = readl(mmio_base + NV_INT_ENABLE_MCP55); mask &= ~(NV_INT_ALL_MCP55 << shift); writel(mask, mmio_base + NV_INT_ENABLE_MCP55); - ata_sff_freeze(ap); } static void nv_mcp55_thaw(struct ata_port *ap) @@ -1687,7 +1686,6 @@ static void nv_mcp55_thaw(struct ata_port *ap) mask = readl(mmio_base + NV_INT_ENABLE_MCP55); mask |= (NV_INT_MASK_MCP55 << shift); writel(mask, mmio_base + NV_INT_ENABLE_MCP55); - ata_sff_thaw(ap); } static void nv_adma_error_handler(struct ata_port *ap) @@ -2478,8 +2476,7 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); - return ata_host_activate(host, pdev->irq, ipriv->irq_handler, - IRQF_SHARED, ipriv->sht); + return ata_pci_sff_activate_host(host, ipriv->irq_handler, ipriv->sht); } #ifdef CONFIG_PM diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 02efd9a83d26..e35596b97853 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -558,6 +558,19 @@ static void svia_configure(struct pci_dev *pdev) tmp8 |= NATIVE_MODE_ALL; pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); } + + /* + * vt6421 has problems talking to some drives. The following + * is the magic fix from Joseph Chan . + * Please add proper documentation if possible. + * + * https://bugzilla.kernel.org/show_bug.cgi?id=15173 + */ + if (pdev->device == 0x3249) { + pci_read_config_byte(pdev, 0x52, &tmp8); + tmp8 |= 1 << 2; + pci_write_config_byte(pdev, 0x52, tmp8); + } } static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index c5f5186d62a3..a73f10278171 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -774,7 +774,8 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci) sk_for_each(s, node, head) { vcc = atm_sk(s); if (vcc->dev == dev && vcc->vci == vci && - vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE) + vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE && + test_bit(ATM_VF_READY, &vcc->flags)) goto out; } vcc = NULL; @@ -900,6 +901,10 @@ static void pclose(struct atm_vcc *vcc) clear_bit(ATM_VF_ADDR, &vcc->flags); clear_bit(ATM_VF_READY, &vcc->flags); + /* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the + tasklet has finished processing any incoming packets (and, more to + the point, using the vcc pointer). */ + tasklet_unlock_wait(&card->tlet); return; } diff --git a/drivers/base/core.c b/drivers/base/core.c index 109317948d5d..f33d768164ac 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -603,6 +603,7 @@ static struct kobject *get_device_parent(struct device *dev, int retval; if (dev->class) { + static DEFINE_MUTEX(gdp_mutex); struct kobject *kobj = NULL; struct kobject *parent_kobj; struct kobject *k; @@ -619,6 +620,8 @@ static struct kobject *get_device_parent(struct device *dev, else parent_kobj = &parent->kobj; + mutex_lock(&gdp_mutex); + /* find our class-directory at the parent and reference it */ spin_lock(&dev->class->p->class_dirs.list_lock); list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) @@ -627,20 +630,26 @@ static struct kobject *get_device_parent(struct device *dev, break; } spin_unlock(&dev->class->p->class_dirs.list_lock); - if (kobj) + if (kobj) { + mutex_unlock(&gdp_mutex); return kobj; + } /* or create a new class-directory at the parent device */ k = kobject_create(); - if (!k) + if (!k) { + mutex_unlock(&gdp_mutex); return NULL; + } k->kset = &dev->class->p->class_dirs; retval = kobject_add(k, parent_kobj, "%s", dev->class->name); if (retval < 0) { + mutex_unlock(&gdp_mutex); kobject_put(k); return NULL; } /* do not emit an uevent for this simple "glue" directory */ + mutex_unlock(&gdp_mutex); return k; } diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index e62a4ccea54d..1e2196fef1c7 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -149,7 +149,7 @@ static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf) /* display offline cpus < nr_cpu_ids */ if (!alloc_cpumask_var(&offline, GFP_KERNEL)) return -ENOMEM; - cpumask_complement(offline, cpu_online_mask); + cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask); n = cpulist_scnprintf(buf, len, offline); free_cpumask_var(offline); diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 33faaa22a19d..4d809667815e 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -295,6 +295,19 @@ int devtmpfs_delete_node(struct device *dev) if (dentry->d_inode) { err = vfs_getattr(nd.path.mnt, dentry, &stat); if (!err && dev_mynode(dev, dentry->d_inode, &stat)) { + struct iattr newattrs; + /* + * before unlinking this node, reset permissions + * of possible references like hardlinks + */ + newattrs.ia_uid = 0; + newattrs.ia_gid = 0; + newattrs.ia_mode = stat.mode & ~0777; + newattrs.ia_valid = + ATTR_UID|ATTR_GID|ATTR_MODE; + mutex_lock(&dentry->d_inode->i_mutex); + notify_change(dentry, &newattrs); + mutex_unlock(&dentry->d_inode->i_mutex); err = vfs_unlink(nd.path.dentry->d_inode, dentry); if (!err || err == -ENOENT) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index cb07001513f1..de2e5e25f5be 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -125,6 +125,17 @@ static ssize_t firmware_loading_show(struct device *dev, return sprintf(buf, "%d\n", loading); } +static void firmware_free_data(const struct firmware *fw) +{ + int i; + vunmap(fw->data); + if (fw->pages) { + for (i = 0; i < PFN_UP(fw->size); i++) + __free_page(fw->pages[i]); + kfree(fw->pages); + } +} + /* Some architectures don't have PAGE_KERNEL_RO */ #ifndef PAGE_KERNEL_RO #define PAGE_KERNEL_RO PAGE_KERNEL @@ -157,21 +168,21 @@ static ssize_t firmware_loading_store(struct device *dev, mutex_unlock(&fw_lock); break; } - vfree(fw_priv->fw->data); - fw_priv->fw->data = NULL; + firmware_free_data(fw_priv->fw); + memset(fw_priv->fw, 0, sizeof(struct firmware)); + /* If the pages are not owned by 'struct firmware' */ for (i = 0; i < fw_priv->nr_pages; i++) __free_page(fw_priv->pages[i]); kfree(fw_priv->pages); fw_priv->pages = NULL; fw_priv->page_array_size = 0; fw_priv->nr_pages = 0; - fw_priv->fw->size = 0; set_bit(FW_STATUS_LOADING, &fw_priv->status); mutex_unlock(&fw_lock); break; case 0: if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) { - vfree(fw_priv->fw->data); + vunmap(fw_priv->fw->data); fw_priv->fw->data = vmap(fw_priv->pages, fw_priv->nr_pages, 0, PAGE_KERNEL_RO); @@ -179,7 +190,10 @@ static ssize_t firmware_loading_store(struct device *dev, dev_err(dev, "%s: vmap() failed\n", __func__); goto err; } - /* Pages will be freed by vfree() */ + /* Pages are now owned by 'struct firmware' */ + fw_priv->fw->pages = fw_priv->pages; + fw_priv->pages = NULL; + fw_priv->page_array_size = 0; fw_priv->nr_pages = 0; complete(&fw_priv->completion); @@ -572,7 +586,7 @@ release_firmware(const struct firmware *fw) if (fw->data == builtin->data) goto free_fw; } - vfree(fw->data); + firmware_free_data(fw); free_fw: kfree(fw); } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bd112c8c7bcd..1c21a3f23868 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -238,6 +238,8 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, if (ret) goto fail; + file_update_time(file); + transfer_result = lo_do_transfer(lo, WRITE, page, offset, bvec->bv_page, bv_offs, size, IV); copied = size; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1be76318f516..0e9c5646c598 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, + /* Apple iMac11,1 */ + { USB_DEVICE(0x05ac, 0x8215) }, + /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 51ff3ef58ec7..ac2f0f23b6eb 100755 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -265,9 +265,16 @@ static int hci_uart_tty_open(struct tty_struct *tty) BT_DBG("tty %p", tty); + /* FIXME: This btw is bogus, nothing requires the old ldisc to clear + the pointer */ if (hu) return -EEXIST; + /* Error if the tty has no write op instead of leaving an exploitable + hole */ + if (tty->ops->write == NULL) + return -EOPNOTSUPP; + if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { BT_ERR("Can't allocate control structure"); return -ENFILE; diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index ccb1fa89de29..70d56b683630 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig @@ -57,7 +57,7 @@ config AGP_AMD config AGP_AMD64 tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU - depends on AGP && X86 + depends on AGP && X86 && K8_NB default y if GART_IOMMU help This option gives you AGP support for the GLX component of diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 2fb2e6cc322a..c496c8a1a885 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -499,6 +499,10 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, u8 cap_ptr; int err; + /* The Highlander principle */ + if (agp_bridges_found) + return -ENODEV; + cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); if (!cap_ptr) return -ENODEV; @@ -562,6 +566,8 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); + + agp_bridges_found--; } #ifdef CONFIG_PM @@ -709,6 +715,11 @@ static struct pci_device_id agp_amd64_pci_table[] = { MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table); +static DEFINE_PCI_DEVICE_TABLE(agp_amd64_pci_promisc_table) = { + { PCI_DEVICE_CLASS(0, 0) }, + { } +}; + static struct pci_driver agp_amd64_pci_driver = { .name = "agpgart-amd64", .id_table = agp_amd64_pci_table, @@ -733,7 +744,6 @@ int __init agp_amd64_init(void) return err; if (agp_bridges_found == 0) { - struct pci_dev *dev; if (!agp_try_unsupported && !agp_try_unsupported_boot) { printk(KERN_INFO PFX "No supported AGP bridge found.\n"); #ifdef MODULE @@ -749,17 +759,10 @@ int __init agp_amd64_init(void) return -ENODEV; /* Look for any AGP bridge */ - dev = NULL; - err = -ENODEV; - for_each_pci_dev(dev) { - if (!pci_find_capability(dev, PCI_CAP_ID_AGP)) - continue; - /* Only one bridge supported right now */ - if (agp_amd64_probe(dev, NULL) == 0) { - err = 0; - break; - } - } + agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table; + err = driver_attach(&agp_amd64_pci_driver.driver); + if (err == 0 && agp_bridges_found == 0) + err = -ENODEV; } return err; } diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 9047b2714653..dc8a6f70483b 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -488,9 +488,8 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) handle = obj; do { status = acpi_get_object_info(handle, &info); - if (ACPI_SUCCESS(status)) { + if (ACPI_SUCCESS(status) && (info->valid & ACPI_VALID_HID)) { /* TBD check _CID also */ - info->hardware_id.string[sizeof(info->hardware_id.length)-1] = '\0'; match = (strcmp(info->hardware_id.string, "HWP0001") == 0); kfree(info); if (match) { diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 4dcfef05045a..b8e02190bef4 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "agp.h" /* @@ -815,12 +816,6 @@ static void intel_i830_setup_flush(void) intel_i830_fini_flush(); } -static void -do_wbinvd(void *null) -{ - wbinvd(); -} - /* The chipset_flush interface needs to get data that has already been * flushed out of the CPU all the way out to main memory, because the GPU * doesn't snoop those buffers. @@ -837,12 +832,10 @@ static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) memset(pg, 0, 1024); - if (cpu_has_clflush) { + if (cpu_has_clflush) clflush_cache_range(pg, 1024); - } else { - if (on_each_cpu(do_wbinvd, NULL, 1) != 0) - printk(KERN_ERR "Timed out waiting for cache flush.\n"); - } + else if (wbinvd_on_all_cpus() != 0) + printk(KERN_ERR "Timed out waiting for cache flush.\n"); } /* The intel i830 automatically initializes the agp aperture during POST. diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 6c3837a0184d..95fdd4d3a6b1 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -415,14 +415,6 @@ static struct pci_device_id agp_sis_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_760, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { } }; diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 70a770ac0138..006466d2a830 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -476,6 +476,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) if (irq) { unsigned long irq_flags; + if (devp->hd_flags & HPET_SHARED_IRQ) { + /* + * To prevent the interrupt handler from seeing an + * unwanted interrupt status bit, program the timer + * so that it will not fire in the near future ... + */ + writel(readl(&timer->hpet_config) & ~Tn_TYPE_CNF_MASK, + &timer->hpet_config); + write_counter(read_counter(&hpet->hpet_mc), + &timer->hpet_compare); + /* ... and clear any left-over status. */ + isr = 1 << (devp - devp->hd_hpets->hp_dev); + writel(isr, &hpet->hpet_isr); + } + sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); irq_flags = devp->hd_flags & HPET_SHARED_IRQ ? IRQF_SHARED : IRQF_DISABLED; @@ -970,6 +985,8 @@ static int hpet_acpi_add(struct acpi_device *device) return -ENODEV; if (!data.hd_address || !data.hd_nirqs) { + if (data.hd_address) + iounmap(data.hd_address); printk("%s: no address or irqs in _CRS\n", __func__); return -ENODEV; } diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index d2e698096ace..abae8c992594 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -310,9 +310,14 @@ static void deliver_recv_msg(struct smi_info *smi_info, { /* Deliver the message to the upper layer with the lock released. */ - spin_unlock(&(smi_info->si_lock)); - ipmi_smi_msg_received(smi_info->intf, msg); - spin_lock(&(smi_info->si_lock)); + + if (smi_info->run_to_completion) { + ipmi_smi_msg_received(smi_info->intf, msg); + } else { + spin_unlock(&(smi_info->si_lock)); + ipmi_smi_msg_received(smi_info->intf, msg); + spin_lock(&(smi_info->si_lock)); + } } static void return_hosed_msg(struct smi_info *smi_info, int cCode) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 6df298845b3a..ba1db9b601d2 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -837,10 +837,11 @@ static const struct file_operations zero_fops = { /* * capabilities for /dev/zero * - permits private mappings, "copies" are taken of the source of zeros + * - no writeback happens */ static struct backing_dev_info zero_bdi = { .name = "char/mem", - .capabilities = BDI_CAP_MAP_COPY, + .capabilities = BDI_CAP_MAP_COPY | BDI_CAP_NO_ACCT_AND_WRITEBACK, }; static const struct file_operations full_fops = { diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 88cee4099be9..71f0d72fc2f3 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -265,10 +265,16 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, unsigned char contents[NVRAM_BYTES]; unsigned i = *ppos; unsigned char *tmp; - int len; - len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count; - if (copy_from_user(contents, buf, len)) + if (i >= NVRAM_BYTES) + return 0; /* Past EOF */ + + if (count > NVRAM_BYTES - i) + count = NVRAM_BYTES - i; + if (count > NVRAM_BYTES) + return -EFAULT; /* Can't happen, but prove it to gcc */ + + if (copy_from_user(contents, buf, count)) return -EFAULT; spin_lock_irq(&rtc_lock); @@ -276,7 +282,7 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, if (!__nvram_check_checksum()) goto checksum_err; - for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp) + for (tmp = contents; count--; ++i, ++tmp) __nvram_write_byte(*tmp, i); __nvram_set_checksum(); diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index caf6e4d19469..a08c8994c89d 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -4164,6 +4164,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (cmd != SIOCWANDEV) return hdlc_ioctl(dev, ifr, cmd); + memset(&new_line, 0, size); + switch(ifr->ifr_settings.type) { case IF_GET_IFACE: /* return current sync_serial_settings */ diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 64acd05f71c8..9abc3a19d53a 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -247,6 +247,7 @@ static const struct file_operations raw_fops = { .aio_read = generic_file_aio_read, .write = do_sync_write, .aio_write = blkdev_aio_write, + .fsync = block_fsync, .open = raw_open, .release= raw_release, .ioctl = raw_ioctl, diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 8e00b4ddd083..792868d24f2a 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -224,6 +224,7 @@ struct tpm_readpubek_params_out { u8 algorithm[4]; u8 encscheme[2]; u8 sigscheme[2]; + __be32 paramsize; u8 parameters[12]; /*assuming RSA*/ __be32 keysize; u8 modulus[256]; diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 0b73e4ec1add..ca15c04e5a8d 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -257,6 +257,10 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) return size; } +static int itpm; +module_param(itpm, bool, 0444); +MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)"); + /* * If interrupts are used (signaled by an irq set in the vendor structure) * tpm.c can skip polling for the data to be available as the interrupt is @@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &chip->vendor.int_queue); status = tpm_tis_status(chip); - if ((status & TPM_STS_DATA_EXPECT) == 0) { + if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { rc = -EIO; goto out_err; } @@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, "1.2 TPM (device-id 0x%X, rev-id %d)\n", vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); + if (itpm) + dev_info(dev, "Intel iTPM workaround enabled\n"); + + /* Figure out the capabilities */ intfcaps = ioread32(chip->vendor.iobase + @@ -614,7 +622,14 @@ static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) static int tpm_tis_pnp_resume(struct pnp_dev *dev) { - return tpm_pm_resume(&dev->dev); + struct tpm_chip *chip = pnp_get_drvdata(dev); + int ret; + + ret = tpm_pm_resume(&dev->dev); + if (!ret) + tpm_continue_selftest(chip); + + return ret; } static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { @@ -629,6 +644,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { {"", 0}, /* User Specified */ {"", 0} /* Terminator */ }; +MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) { diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index 66fa4e10d76b..9605ee5b931e 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c @@ -247,7 +247,8 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, { int copied = 0; do { - int space = tty_buffer_request_room(tty, size - copied); + int goal = min(size - copied, TTY_BUFFER_PAGE); + int space = tty_buffer_request_room(tty, goal); struct tty_buffer *tb = tty->buf.tail; /* If there is no space then tb may be NULL */ if (unlikely(space == 0)) @@ -283,7 +284,8 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, { int copied = 0; do { - int space = tty_buffer_request_room(tty, size - copied); + int goal = min(size - copied, TTY_BUFFER_PAGE); + int space = tty_buffer_request_room(tty, goal); struct tty_buffer *tb = tty->buf.tail; /* If there is no space then tb may be NULL */ if (unlikely(space == 0)) @@ -410,7 +412,8 @@ static void flush_to_ldisc(struct work_struct *work) spin_lock_irqsave(&tty->buf.lock, flags); if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { - struct tty_buffer *head; + struct tty_buffer *head, *tail = tty->buf.tail; + int seen_tail = 0; while ((head = tty->buf.head) != NULL) { int count; char *char_buf; @@ -420,6 +423,15 @@ static void flush_to_ldisc(struct work_struct *work) if (!count) { if (head->next == NULL) break; + /* + There's a possibility tty might get new buffer + added during the unlock window below. We could + end up spinning in here forever hogging the CPU + completely. To avoid this let's have a rest each + time we processed the tail buffer. + */ + if (tail == head) + seen_tail = 1; tty->buf.head = head->next; tty_buffer_free(tty, head); continue; @@ -429,7 +441,7 @@ static void flush_to_ldisc(struct work_struct *work) line discipline as we want to empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) break; - if (!tty->receive_room) { + if (!tty->receive_room || seen_tail) { schedule_delayed_work(&tty->buf.work, 1); break; } diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 05cab2cea85e..53ffcfc1154b 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1408,6 +1408,8 @@ static void release_one_tty(struct work_struct *work) list_del_init(&tty->tty_files); file_list_unlock(); + put_pid(tty->pgrp); + put_pid(tty->session); free_tty_struct(tty); } diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index feb55075819b..8b9f1a5c8be8 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c @@ -45,6 +45,7 @@ static DEFINE_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); +static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle); /* Line disc dispatch table */ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; @@ -81,6 +82,7 @@ static void put_ldisc(struct tty_ldisc *ld) return; } local_irq_restore(flags); + wake_up(&tty_ldisc_idle); } /** @@ -442,9 +444,14 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) { + int ret; + WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); - if (ld->ops->open) - return ld->ops->open(tty); + if (ld->ops->open) { + ret = ld->ops->open(tty); + if (ret) + clear_bit(TTY_LDISC_OPEN, &tty->flags); + } return 0; } @@ -521,6 +528,23 @@ static int tty_ldisc_halt(struct tty_struct *tty) return cancel_delayed_work_sync(&tty->buf.work); } +/** + * tty_ldisc_wait_idle - wait for the ldisc to become idle + * @tty: tty to wait for + * + * Wait for the line discipline to become idle. The discipline must + * have been halted for this to guarantee it remains idle. + */ +static int tty_ldisc_wait_idle(struct tty_struct *tty) +{ + int ret; + ret = wait_event_interruptible_timeout(tty_ldisc_idle, + atomic_read(&tty->ldisc->users) == 1, 5 * HZ); + if (ret < 0) + return ret; + return ret > 0 ? 0 : -EBUSY; +} + /** * tty_set_ldisc - set line discipline * @tty: the terminal to set @@ -616,7 +640,16 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) flush_scheduled_work(); + retval = tty_ldisc_wait_idle(tty); + mutex_lock(&tty->ldisc_mutex); + + /* handle wait idle failure locked */ + if (retval) { + tty_ldisc_put(new_ldisc); + goto enable; + } + if (test_bit(TTY_HUPPED, &tty->flags)) { /* We were raced by the hangup method. It will have stomped the ldisc data and closed the ldisc down */ @@ -649,6 +682,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_put(o_ldisc); +enable: /* * Allow ldisc referencing to occur again */ @@ -687,14 +721,18 @@ static void tty_reset_termios(struct tty_struct *tty) /** * tty_ldisc_reinit - reinitialise the tty ldisc * @tty: tty to reinit + * @ldisc: line discipline to reinitialize * - * Switch the tty back to N_TTY line discipline and leave the - * ldisc state closed + * Switch the tty to a line discipline and leave the ldisc + * state closed */ -static void tty_ldisc_reinit(struct tty_struct *tty) +static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) { - struct tty_ldisc *ld; + struct tty_ldisc *ld = tty_ldisc_get(ldisc); + + if (IS_ERR(ld)) + return -1; tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); @@ -702,10 +740,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty) /* * Switch the line discipline back */ - ld = tty_ldisc_get(N_TTY); - BUG_ON(IS_ERR(ld)); tty_ldisc_assign(tty, ld); - tty_set_termios_ldisc(tty, N_TTY); + tty_set_termios_ldisc(tty, ldisc); + + return 0; } /** @@ -726,6 +764,8 @@ static void tty_ldisc_reinit(struct tty_struct *tty) void tty_ldisc_hangup(struct tty_struct *tty) { struct tty_ldisc *ld; + int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; + int err = 0; /* * FIXME! What are the locking issues here? This may me overdoing @@ -753,25 +793,35 @@ void tty_ldisc_hangup(struct tty_struct *tty) wake_up_interruptible_poll(&tty->read_wait, POLLIN); /* * Shutdown the current line discipline, and reset it to - * N_TTY. + * N_TTY if need be. + * + * Avoid racing set_ldisc or tty_ldisc_release */ - if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { - /* Avoid racing set_ldisc or tty_ldisc_release */ - mutex_lock(&tty->ldisc_mutex); - tty_ldisc_halt(tty); - if (tty->ldisc) { /* Not yet closed */ - /* Switch back to N_TTY */ - tty_ldisc_reinit(tty); - /* At this point we have a closed ldisc and we want to - reopen it. We could defer this to the next open but - it means auditing a lot of other paths so this is - a FIXME */ - WARN_ON(tty_ldisc_open(tty, tty->ldisc)); - tty_ldisc_enable(tty); + mutex_lock(&tty->ldisc_mutex); + tty_ldisc_halt(tty); + /* At this point we have a closed ldisc and we want to + reopen it. We could defer this to the next open but + it means auditing a lot of other paths so this is + a FIXME */ + if (tty->ldisc) { /* Not yet closed */ + if (reset == 0) { + + if (!tty_ldisc_reinit(tty, tty->termios->c_line)) + err = tty_ldisc_open(tty, tty->ldisc); + else + err = 1; } - mutex_unlock(&tty->ldisc_mutex); - tty_reset_termios(tty); + /* If the re-open fails or we reset then go to N_TTY. The + N_TTY open cannot fail */ + if (reset || err) { + BUG_ON(tty_ldisc_reinit(tty, N_TTY)); + WARN_ON(tty_ldisc_open(tty, tty->ldisc)); + } + tty_ldisc_enable(tty); } + mutex_unlock(&tty->ldisc_mutex); + if (reset) + tty_reset_termios(tty); } /** diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 6aa10284104a..6351a2625dfe 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -503,6 +503,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, struct kbd_struct * kbd; unsigned int console; unsigned char ucval; + unsigned int uival; void __user *up = (void __user *)arg; int i, perm; int ret = 0; @@ -657,7 +658,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, break; case KDGETMODE: - ucval = vc->vc_mode; + uival = vc->vc_mode; goto setint; case KDMAPDISP: @@ -695,7 +696,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, break; case KDGKBMODE: - ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : + uival = ((kbd->kbdmode == VC_RAW) ? K_RAW : (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : K_XLATE); @@ -717,9 +718,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, break; case KDGKBMETA: - ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); + uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); setint: - ret = put_user(ucval, (int __user *)arg); + ret = put_user(uival, (int __user *)arg); break; case KDGETKEYCODE: @@ -949,7 +950,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, for (i = 0; i < MAX_NR_CONSOLES; ++i) if (! VT_IS_IN_USE(i)) break; - ucval = i < MAX_NR_CONSOLES ? (i+1) : -1; + uival = i < MAX_NR_CONSOLES ? (i+1) : -1; goto setint; /* diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 6b3e0c2f33e2..234d9f6bc696 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -413,18 +413,10 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) static int sh_cmt_clocksource_enable(struct clocksource *cs) { struct sh_cmt_priv *p = cs_to_sh_cmt(cs); - int ret; p->total_cycles = 0; - ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); - if (ret) - return ret; - - /* TODO: calculate good shift from rate and counter bit width */ - cs->shift = 0; - cs->mult = clocksource_hz2mult(p->rate, cs->shift); - return 0; + return sh_cmt_start(p, FLAG_CLOCKSOURCE); } static void sh_cmt_clocksource_disable(struct clocksource *cs) @@ -444,7 +436,18 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, cs->disable = sh_cmt_clocksource_disable; cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; + + /* clk_get_rate() needs an enabled clock */ + clk_enable(p->clk); + p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8; + clk_disable(p->clk); + + /* TODO: calculate good shift from rate and counter bit width */ + cs->shift = 10; + cs->mult = clocksource_hz2mult(p->rate, cs->shift); + pr_info("sh_cmt: %s used as clock source\n", cs->name); + clocksource_register(cs); return 0; } @@ -603,18 +606,13 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) p->irqaction.handler = sh_cmt_interrupt; p->irqaction.dev_id = p; p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL; - ret = setup_irq(irq, &p->irqaction); - if (ret) { - pr_err("sh_cmt: failed to request irq %d\n", irq); - goto err1; - } /* get hold of clock */ p->clk = clk_get(&p->pdev->dev, cfg->clk); if (IS_ERR(p->clk)) { pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk); ret = PTR_ERR(p->clk); - goto err2; + goto err1; } if (resource_size(res) == 6) { @@ -627,14 +625,25 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) p->clear_bits = ~0xc000; } - return sh_cmt_register(p, cfg->name, - cfg->clockevent_rating, - cfg->clocksource_rating); - err2: - remove_irq(irq, &p->irqaction); - err1: + ret = sh_cmt_register(p, cfg->name, + cfg->clockevent_rating, + cfg->clocksource_rating); + if (ret) { + pr_err("sh_cmt: registration failed\n"); + goto err1; + } + + ret = setup_irq(irq, &p->irqaction); + if (ret) { + pr_err("sh_cmt: failed to request irq %d\n", irq); + goto err1; + } + + return 0; + +err1: iounmap(p->mapbase); - err0: +err0: return ret; } diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 973e714d6051..4c8a759e60cd 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -221,15 +221,15 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p, ced->cpumask = cpumask_of(0); ced->set_mode = sh_mtu2_clock_event_mode; + pr_info("sh_mtu2: %s used for clock events\n", ced->name); + clockevents_register_device(ced); + ret = setup_irq(p->irqaction.irq, &p->irqaction); if (ret) { pr_err("sh_mtu2: failed to request irq %d\n", p->irqaction.irq); return; } - - pr_info("sh_mtu2: %s used for clock events\n", ced->name); - clockevents_register_device(ced); } static int sh_mtu2_register(struct sh_mtu2_priv *p, char *name, diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 93c2322feab7..c0732466fb87 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -199,16 +199,8 @@ static cycle_t sh_tmu_clocksource_read(struct clocksource *cs) static int sh_tmu_clocksource_enable(struct clocksource *cs) { struct sh_tmu_priv *p = cs_to_sh_tmu(cs); - int ret; - ret = sh_tmu_enable(p); - if (ret) - return ret; - - /* TODO: calculate good shift from rate and counter bit width */ - cs->shift = 10; - cs->mult = clocksource_hz2mult(p->rate, cs->shift); - return 0; + return sh_tmu_enable(p); } static void sh_tmu_clocksource_disable(struct clocksource *cs) @@ -228,6 +220,16 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, cs->disable = sh_tmu_clocksource_disable; cs->mask = CLOCKSOURCE_MASK(32); cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; + + /* clk_get_rate() needs an enabled clock */ + clk_enable(p->clk); + /* channel will be configured at parent clock / 4 */ + p->rate = clk_get_rate(p->clk) / 4; + clk_disable(p->clk); + /* TODO: calculate good shift from rate and counter bit width */ + cs->shift = 10; + cs->mult = clocksource_hz2mult(p->rate, cs->shift); + pr_info("sh_tmu: %s used as clock source\n", cs->name); clocksource_register(cs); return 0; @@ -323,15 +325,15 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, ced->set_next_event = sh_tmu_clock_event_next; ced->set_mode = sh_tmu_clock_event_mode; + pr_info("sh_tmu: %s used for clock events\n", ced->name); + clockevents_register_device(ced); + ret = setup_irq(p->irqaction.irq, &p->irqaction); if (ret) { pr_err("sh_tmu: failed to request irq %d\n", p->irqaction.irq); return; } - - pr_info("sh_tmu: %s used for clock events\n", ced->name); - clockevents_register_device(ced); } static int sh_tmu_register(struct sh_tmu_priv *p, char *name, diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index ff57c40e9b8b..c18e65e572c7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1741,17 +1741,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, dprintk("governor switch\n"); /* end old governor */ - if (data->governor) { - /* - * Need to release the rwsem around governor - * stop due to lock dependency between - * cancel_delayed_work_sync and the read lock - * taken in the delayed work handler. - */ - unlock_policy_rwsem_write(data->cpu); + if (data->governor) __cpufreq_governor(data, CPUFREQ_GOV_STOP); - lock_policy_rwsem_write(data->cpu); - } /* start new governor */ data->governor = policy->governor; diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 73655aeb3a60..f8e57c6303f2 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -101,7 +101,6 @@ struct menu_device { unsigned int expected_us; u64 predicted_us; - unsigned int measured_us; unsigned int exit_us; unsigned int bucket; u64 correction_factor[BUCKETS]; @@ -187,14 +186,14 @@ static int menu_select(struct cpuidle_device *dev) int i; int multiplier; - data->last_state_idx = 0; - data->exit_us = 0; - if (data->needs_update) { menu_update(dev); data->needs_update = 0; } + data->last_state_idx = 0; + data->exit_us = 0; + /* Special case when user has set very strict latency requirement */ if (unlikely(latency_req == 0)) return 0; @@ -294,7 +293,7 @@ static void menu_update(struct cpuidle_device *dev) new_factor = data->correction_factor[data->bucket] * (DECAY - 1) / DECAY; - if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING) + if (data->expected_us > 0 && measured_us < MAX_INTERESTING) new_factor += RESOLUTION * measured_us / data->expected_us; else /* diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 84c51e177269..71e64824e8f7 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -285,7 +285,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, if (initial) asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) - : "d" (control_word), "b" (key), "c" (count)); + : "d" (control_word), "b" (key), "c" (initial)); asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 466ab10c1ff1..f2b44d51d826 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -161,7 +161,7 @@ static int mv_is_err_intr(u32 intr_cause) static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan) { - u32 val = (1 << (1 + (chan->idx * 16))); + u32 val = ~(1 << (chan->idx * 16)); dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val); __raw_writel(val, XOR_INTR_CAUSE(chan)); } diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 01bc8e232456..2aa339e94968 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -156,7 +156,7 @@ static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 *bandwidth) default: amd64_printk(KERN_ERR, "Unsupported family!\n"); - break; + return -EINVAL; } return amd64_search_set_scrub_rate(pvt->misc_f3_ctl, *bandwidth, min_scrubrate); @@ -1491,7 +1491,7 @@ static inline u64 f10_get_base_addr_offset(u64 sys_addr, int hi_range_sel, u64 chan_off; if (hi_range_sel) { - if (!(dct_sel_base_addr & 0xFFFFF800) && + if (!(dct_sel_base_addr & 0xFFFF0000) && hole_valid && (sys_addr >= 0x100000000ULL)) chan_off = hole_off << 16; else diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index 713ed7d37247..1999807f078f 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c @@ -295,7 +295,6 @@ static void amd_decode_ls_mce(u64 mc3_status) void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) { u32 ec = ERROR_CODE(regs->nbsl); - u32 xec = EXT_ERROR_CODE(regs->nbsl); if (!handle_errors) return; @@ -311,11 +310,15 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) if (regs->nbsh & K8_NBSH_ERR_CPU_VAL) pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf)); } else { - pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf))); + u8 assoc_cpus = regs->nbsh & 0xf; + + if (assoc_cpus > 0) + pr_cont(", core: %d", fls(assoc_cpus) - 1); + + pr_cont("\n"); } - - pr_emerg("%s.\n", EXT_ERR_MSG(xec)); + pr_emerg("%s.\n", EXT_ERR_MSG(regs->nbsl)); if (BUS_ERROR(ec) && nb_bus_decoder) nb_bus_decoder(node_id, regs); @@ -378,7 +381,7 @@ static void amd_decode_mce(struct mce *m) ((m->status & MCI_STATUS_PCC) ? "yes" : "no")); /* do the two bits[14:13] together */ - ecc = m->status & (3ULL << 45); + ecc = (m->status >> 45) & 0x3; if (ecc) pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U")); diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index ed635ae2b5d3..3fc2ceb6d715 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -239,7 +239,7 @@ void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) static void fw_card_bm_work(struct work_struct *work) { struct fw_card *card = container_of(work, struct fw_card, work.work); - struct fw_device *root_device; + struct fw_device *root_device, *irm_device; struct fw_node *root_node; unsigned long flags; int root_id, new_root_id, irm_id, local_id; @@ -247,6 +247,7 @@ static void fw_card_bm_work(struct work_struct *work) bool do_reset = false; bool root_device_is_running; bool root_device_is_cmc; + bool irm_is_1394_1995_only; spin_lock_irqsave(&card->lock, flags); @@ -256,12 +257,18 @@ static void fw_card_bm_work(struct work_struct *work) } generation = card->generation; + root_node = card->root_node; fw_node_get(root_node); root_device = root_node->data; root_device_is_running = root_device && atomic_read(&root_device->state) == FW_DEVICE_RUNNING; root_device_is_cmc = root_device && root_device->cmc; + + irm_device = card->irm_node->data; + irm_is_1394_1995_only = irm_device && irm_device->config_rom && + (irm_device->config_rom[2] & 0x000000f0) == 0; + root_id = root_node->node_id; irm_id = card->irm_node->node_id; local_id = card->local_node->node_id; @@ -284,8 +291,15 @@ static void fw_card_bm_work(struct work_struct *work) if (!card->irm_node->link_on) { new_root_id = local_id; - fw_notify("IRM has link off, making local node (%02x) root.\n", - new_root_id); + fw_notify("%s, making local node (%02x) root.\n", + "IRM has link off", new_root_id); + goto pick_me; + } + + if (irm_is_1394_1995_only) { + new_root_id = local_id; + fw_notify("%s, making local node (%02x) root.\n", + "IRM is not 1394a compliant", new_root_id); goto pick_me; } @@ -324,8 +338,8 @@ static void fw_card_bm_work(struct work_struct *work) * root, and thus, IRM. */ new_root_id = local_id; - fw_notify("BM lock failed, making local node (%02x) root.\n", - new_root_id); + fw_notify("%s, making local node (%02x) root.\n", + "BM lock failed", new_root_id); goto pick_me; } } else if (card->bm_generation != generation) { diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 5089331544ed..4560d8ffa171 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -1299,24 +1299,24 @@ static int dispatch_ioctl(struct client *client, int ret; if (_IOC_TYPE(cmd) != '#' || - _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers)) + _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || + _IOC_SIZE(cmd) > sizeof(buffer)) return -EINVAL; - if (_IOC_DIR(cmd) & _IOC_WRITE) { - if (_IOC_SIZE(cmd) > sizeof(buffer) || - copy_from_user(buffer, arg, _IOC_SIZE(cmd))) + if (_IOC_DIR(cmd) == _IOC_READ) + memset(&buffer, 0, _IOC_SIZE(cmd)); + + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(buffer, arg, _IOC_SIZE(cmd))) return -EFAULT; - } ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer); if (ret < 0) return ret; - if (_IOC_DIR(cmd) & _IOC_READ) { - if (_IOC_SIZE(cmd) > sizeof(buffer) || - copy_to_user(arg, buffer, _IOC_SIZE(cmd))) + if (_IOC_DIR(cmd) & _IOC_READ) + if (copy_to_user(arg, buffer, _IOC_SIZE(cmd))) return -EFAULT; - } return ret; } diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9d0dfcbe2c1c..17e2b1740202 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -463,6 +463,7 @@ static int read_bus_info_block(struct fw_device *device, int generation) return -ENOMEM; stack = &rom[READ_BIB_ROM_SIZE]; + memset(rom, 0, sizeof(*rom) * READ_BIB_ROM_SIZE); device->max_speed = SCODE_100; diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 720b39b0b4ed..8e7a100a4b6d 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -628,7 +628,7 @@ static void ar_context_tasklet(unsigned long data) d = &ab->descriptor; if (d->res_count == 0) { - size_t size, rest, offset; + size_t size, size2, rest, pktsize, size3, offset; dma_addr_t start_bus; void *start; @@ -639,25 +639,61 @@ static void ar_context_tasklet(unsigned long data) */ offset = offsetof(struct ar_buffer, data); - start = buffer = ab; + start = ab; start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; + buffer = ab->data; ab = ab->next; d = &ab->descriptor; - size = buffer + PAGE_SIZE - ctx->pointer; + size = start + PAGE_SIZE - ctx->pointer; + /* valid buffer data in the next page */ rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); + /* what actually fits in this page */ + size2 = min(rest, (size_t)PAGE_SIZE - offset - size); memmove(buffer, ctx->pointer, size); - memcpy(buffer + size, ab->data, rest); - ctx->current_buffer = ab; - ctx->pointer = (void *) ab->data + rest; - end = buffer + size + rest; + memcpy(buffer + size, ab->data, size2); - while (buffer < end) - buffer = handle_ar_packet(ctx, buffer); + while (size > 0) { + void *next = handle_ar_packet(ctx, buffer); + pktsize = next - buffer; + if (pktsize >= size) { + /* + * We have handled all the data that was + * originally in this page, so we can now + * continue in the next page. + */ + buffer = next; + break; + } + /* move the next packet to the start of the buffer */ + memmove(buffer, next, size + size2 - pktsize); + size -= pktsize; + /* fill up this page again */ + size3 = min(rest - size2, + (size_t)PAGE_SIZE - offset - size - size2); + memcpy(buffer + size + size2, + (void *) ab->data + size2, size3); + size2 += size3; + } - dma_free_coherent(ohci->card.device, PAGE_SIZE, - start, start_bus); - ar_context_add_page(ctx); + if (rest > 0) { + /* handle the packets that are fully in the next page */ + buffer = (void *) ab->data + + (buffer - (start + offset + size)); + end = (void *) ab->data + rest; + + while (buffer < end) + buffer = handle_ar_packet(ctx, buffer); + + ctx->current_buffer = ab; + ctx->pointer = end; + + dma_free_coherent(ohci->card.device, PAGE_SIZE, + start, start_bus); + ar_context_add_page(ctx); + } else { + ctx->pointer = start + PAGE_SIZE; + } } else { buffer = ctx->pointer; ctx->pointer = end = diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c index f9c09a54ec7f..9a270478acac 100644 --- a/drivers/gpio/wm831x-gpio.c +++ b/drivers/gpio/wm831x-gpio.c @@ -61,16 +61,6 @@ static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) return 0; } -static int wm831x_gpio_direction_out(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); - struct wm831x *wm831x = wm831x_gpio->wm831x; - - return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, - WM831X_GPN_DIR | WM831X_GPN_TRI, 0); -} - static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); @@ -80,6 +70,24 @@ static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) value << offset); } +static int wm831x_gpio_direction_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); + struct wm831x *wm831x = wm831x_gpio->wm831x; + int ret; + + ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, + WM831X_GPN_DIR | WM831X_GPN_TRI, 0); + if (ret < 0) + return ret; + + /* Can only set GPIO state once it's in output mode */ + wm831x_gpio_set(chip, offset, value); + + return 0; +} + #ifdef CONFIG_DEBUG_FS static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index afed886cb0fe..1b8745dfd457 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (connector->status == connector_status_disconnected) { DRM_DEBUG_KMS("%s is disconnected\n", drm_get_connector_name(connector)); + drm_mode_connector_update_edid_property(connector, NULL); goto prune; } @@ -924,13 +925,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) mode_changed = true; if (mode_changed) { - old_fb = set->crtc->fb; - set->crtc->fb = set->fb; set->crtc->enabled = (set->mode != NULL); if (set->mode != NULL) { DRM_DEBUG_KMS("attempting to set mode from" " userspace\n"); drm_mode_debug_printmodeline(set->mode); + old_fb = set->crtc->fb; + set->crtc->fb = set->fb; if (!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x, set->y, old_fb)) { diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index a75ca63deea6..0e27d98b2b9f 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -470,7 +470,9 @@ int drm_ioctl(struct inode *inode, struct file *filp, retcode = -EFAULT; goto err_i1; } - } + } else + memset(kdata, 0, _IOC_SIZE(cmd)); + retcode = func(dev, kdata, file_priv); if (cmd & IOC_OUT) { diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index b54ba63d506e..1097dece323c 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -85,6 +85,8 @@ static struct edid_quirk { /* Envision Peripherals, Inc. EN-7100e */ { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH }, + /* Envision EN2028 */ + { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 }, /* Funai Electronics PM36B */ { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | @@ -322,7 +324,7 @@ static struct drm_display_mode drm_dmt_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@85Hz */ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072, - 1072, 1376, 0, 768, 769, 772, 808, 0, + 1168, 1376, 0, 768, 769, 772, 808, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */ { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, @@ -563,8 +565,8 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0, false); mode->hdisplay = 1366; - mode->vsync_start = mode->vsync_start - 1; - mode->vsync_end = mode->vsync_end - 1; + mode->hsync_start = mode->hsync_start - 1; + mode->hsync_end = mode->hsync_end - 1; return mode; } mode = NULL; @@ -653,15 +655,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vtotal = mode->vdisplay + vblank; - /* perform the basic check for the detailed timing */ - if (mode->hsync_end > mode->htotal || - mode->vsync_end > mode->vtotal) { - drm_mode_destroy(dev, mode); - DRM_DEBUG_KMS("Incorrect detailed timing. " - "Sync is beyond the blank.\n"); - return NULL; - } - /* Some EDIDs have bogus h/vtotal values */ if (mode->hsync_end > mode->htotal) mode->htotal = mode->hsync_end + 1; @@ -834,8 +827,57 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid return modes; } +static int add_detailed_modes(struct drm_connector *connector, + struct detailed_timing *timing, + struct edid *edid, u32 quirks, int preferred) +{ + int i, modes = 0; + struct detailed_non_pixel *data = &timing->data.other_data; + int timing_level = standard_timing_level(edid); + struct drm_display_mode *newmode; + struct drm_device *dev = connector->dev; + + if (timing->pixel_clock) { + newmode = drm_mode_detailed(dev, edid, timing, quirks); + if (!newmode) + return 0; + + if (preferred) + newmode->type |= DRM_MODE_TYPE_PREFERRED; + + drm_mode_probed_add(connector, newmode); + return 1; + } + + /* other timing types */ + switch (data->type) { + case EDID_DETAIL_MONITOR_RANGE: + /* Get monitor range data */ + break; + case EDID_DETAIL_STD_MODES: + /* Six modes per detailed section */ + for (i = 0; i < 6; i++) { + struct std_timing *std; + struct drm_display_mode *newmode; + + std = &data->data.timings[i]; + newmode = drm_mode_std(dev, std, edid->revision, + timing_level); + if (newmode) { + drm_mode_probed_add(connector, newmode); + modes++; + } + } + break; + default: + break; + } + + return modes; +} + /** - * add_detailed_modes - get detailed mode info from EDID data + * add_detailed_info - get detailed mode info from EDID data * @connector: attached connector * @edid: EDID block to scan * @quirks: quirks to apply @@ -846,67 +888,24 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid static int add_detailed_info(struct drm_connector *connector, struct edid *edid, u32 quirks) { - struct drm_device *dev = connector->dev; - int i, j, modes = 0; - int timing_level; - - timing_level = standard_timing_level(edid); + int i, modes = 0; for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { struct detailed_timing *timing = &edid->detailed_timings[i]; - struct detailed_non_pixel *data = &timing->data.other_data; - struct drm_display_mode *newmode; + int preferred = (i == 0) && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING); - /* X server check is version 1.1 or higher */ - if (edid->version == 1 && edid->revision >= 1 && - !timing->pixel_clock) { - /* Other timing or info */ - switch (data->type) { - case EDID_DETAIL_MONITOR_SERIAL: - break; - case EDID_DETAIL_MONITOR_STRING: - break; - case EDID_DETAIL_MONITOR_RANGE: - /* Get monitor range data */ - break; - case EDID_DETAIL_MONITOR_NAME: - break; - case EDID_DETAIL_MONITOR_CPDATA: - break; - case EDID_DETAIL_STD_MODES: - for (j = 0; j < 6; i++) { - struct std_timing *std; - struct drm_display_mode *newmode; + /* In 1.0, only timings are allowed */ + if (!timing->pixel_clock && edid->version == 1 && + edid->revision == 0) + continue; - std = &data->data.timings[j]; - newmode = drm_mode_std(dev, std, - edid->revision, - timing_level); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - break; - default: - break; - } - } else { - newmode = drm_mode_detailed(dev, edid, timing, quirks); - if (!newmode) - continue; - - /* First detailed mode is preferred */ - if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) - newmode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, newmode); - - modes++; - } + modes += add_detailed_modes(connector, timing, edid, quirks, + preferred); } return modes; } + /** * add_detailed_mode_eedid - get detailed mode info from addtional timing * EDID block @@ -920,12 +919,9 @@ static int add_detailed_info(struct drm_connector *connector, static int add_detailed_info_eedid(struct drm_connector *connector, struct edid *edid, u32 quirks) { - struct drm_device *dev = connector->dev; - int i, j, modes = 0; + int i, modes = 0; char *edid_ext = NULL; struct detailed_timing *timing; - struct detailed_non_pixel *data; - struct drm_display_mode *newmode; int edid_ext_num; int start_offset, end_offset; int timing_level; @@ -976,51 +972,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector, for (i = start_offset; i < end_offset; i += sizeof(struct detailed_timing)) { timing = (struct detailed_timing *)(edid_ext + i); - data = &timing->data.other_data; - /* Detailed mode timing */ - if (timing->pixel_clock) { - newmode = drm_mode_detailed(dev, edid, timing, quirks); - if (!newmode) - continue; - - drm_mode_probed_add(connector, newmode); - - modes++; - continue; - } - - /* Other timing or info */ - switch (data->type) { - case EDID_DETAIL_MONITOR_SERIAL: - break; - case EDID_DETAIL_MONITOR_STRING: - break; - case EDID_DETAIL_MONITOR_RANGE: - /* Get monitor range data */ - break; - case EDID_DETAIL_MONITOR_NAME: - break; - case EDID_DETAIL_MONITOR_CPDATA: - break; - case EDID_DETAIL_STD_MODES: - /* Five modes per detailed section */ - for (j = 0; j < 5; i++) { - struct std_timing *std; - struct drm_display_mode *newmode; - - std = &data->data.timings[j]; - newmode = drm_mode_std(dev, std, - edid->revision, - timing_level); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - break; - default: - break; - } + modes += add_detailed_modes(connector, timing, edid, quirks, 0); } return modes; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 251bc0e3b5ec..ba145531ca03 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -140,14 +140,16 @@ int drm_open(struct inode *inode, struct file *filp) spin_unlock(&dev->count_lock); } out: - mutex_lock(&dev->struct_mutex); - if (minor->type == DRM_MINOR_LEGACY) { - BUG_ON((dev->dev_mapping != NULL) && - (dev->dev_mapping != inode->i_mapping)); - if (dev->dev_mapping == NULL) - dev->dev_mapping = inode->i_mapping; + if (!retcode) { + mutex_lock(&dev->struct_mutex); + if (minor->type == DRM_MINOR_LEGACY) { + if (dev->dev_mapping == NULL) + dev->dev_mapping = inode->i_mapping; + else if (dev->dev_mapping != inode->i_mapping) + retcode = -ENODEV; + } + mutex_unlock(&dev->struct_mutex); } - mutex_unlock(&dev->struct_mutex); return retcode; } diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index 9ecc907384ec..16dce8479e7f 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c @@ -214,7 +214,7 @@ static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo) uint8_t ctl2; if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) { - if (ctl2 & TFP410_CTL_2_HTPLG) + if (ctl2 & TFP410_CTL_2_RSEN) ret = connector_status_connected; else ret = connector_status_disconnected; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index eaa1893b6e9b..c3aca5c4de99 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -683,8 +683,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, ret = copy_from_user(cliprects, batch->cliprects, batch->num_cliprects * sizeof(struct drm_clip_rect)); - if (ret != 0) + if (ret != 0) { + ret = -EFAULT; goto fail_free; + } } mutex_lock(&dev->struct_mutex); @@ -725,8 +727,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, return -ENOMEM; ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); - if (ret != 0) + if (ret != 0) { + ret = -EFAULT; goto fail_batch_free; + } if (cmdbuf->num_cliprects) { cliprects = kcalloc(cmdbuf->num_cliprects, @@ -737,8 +741,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, ret = copy_from_user(cliprects, cmdbuf->cliprects, cmdbuf->num_cliprects * sizeof(struct drm_clip_rect)); - if (ret != 0) + if (ret != 0) { + ret = -EFAULT; goto fail_clip_free; + } } mutex_lock(&dev->struct_mutex); @@ -1526,6 +1532,15 @@ int i915_driver_unload(struct drm_device *dev) } if (drm_core_check_feature(dev, DRIVER_MODESET)) { + /* + * free the memory space allocated for the child device + * config parsed from VBT + */ + if (dev_priv->child_dev && dev_priv->child_dev_num) { + kfree(dev_priv->child_dev); + dev_priv->child_dev = NULL; + dev_priv->child_dev_num = 0; + } drm_irq_uninstall(dev); vga_client_register(dev->pdev, NULL, NULL, NULL); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7f436ec075f6..544923988d13 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -192,6 +192,7 @@ int i965_reset(struct drm_device *dev, u8 flags) } } else { DRM_ERROR("Error occurred. Don't know how to reset this chip.\n"); + mutex_unlock(&dev->struct_mutex); return -ENODEV; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f5d49a7ac745..97163f7f2bad 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -258,7 +258,7 @@ typedef struct drm_i915_private { struct notifier_block lid_notifier; - int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ + int crt_ddc_bus; /* 0 = unknown, else GPIO to use for CRT DDC */ struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */ @@ -555,6 +555,8 @@ typedef struct drm_i915_private { struct timer_list idle_timer; bool busy; u16 orig_clock; + int child_dev_num; + struct child_device_config *child_dev; struct drm_connector *int_lvds_connector; } drm_i915_private_t; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 04da731a70ab..3ada62b8bd38 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1470,9 +1470,6 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) obj_priv->dirty = 0; for (i = 0; i < page_count; i++) { - if (obj_priv->pages[i] == NULL) - break; - if (obj_priv->dirty) set_page_dirty(obj_priv->pages[i]); @@ -2246,7 +2243,6 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, struct address_space *mapping; struct inode *inode; struct page *page; - int ret; if (obj_priv->pages_refcount++ != 0) return 0; @@ -2266,14 +2262,13 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, mapping = inode->i_mapping; for (i = 0; i < page_count; i++) { page = read_cache_page_gfp(mapping, i, - mapping_gfp_mask (mapping) | + GFP_HIGHUSER | __GFP_COLD | + __GFP_RECLAIMABLE | gfpmask); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - i915_gem_object_put_pages(obj); - return ret; - } + if (IS_ERR(page)) + goto err_pages; + obj_priv->pages[i] = page; } @@ -2281,6 +2276,15 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, i915_gem_object_do_bit_17_swizzle(obj); return 0; + +err_pages: + while (i--) + page_cache_release(obj_priv->pages[i]); + + drm_free_large(obj_priv->pages); + obj_priv->pages = NULL; + obj_priv->pages_refcount--; + return PTR_ERR(page); } static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) @@ -2331,6 +2335,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) pitch_val = obj_priv->stride / tile_width; pitch_val = ffs(pitch_val) - 1; + if (obj_priv->tiling_mode == I915_TILING_Y && + HAS_128_BYTE_Y_TILING(dev)) + WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); + else + WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); + val = obj_priv->gtt_offset; if (obj_priv->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; @@ -2606,6 +2616,14 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) return -EINVAL; } + /* If the object is bigger than the entire aperture, reject it early + * before evicting everything in a vain attempt to find space. + */ + if (obj->size > dev->gtt_total) { + DRM_ERROR("Attempting to bind an object larger than the aperture\n"); + return -E2BIG; + } + search_free: free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, obj->size, alignment, 0); @@ -3649,6 +3667,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, if (ret != 0) { DRM_ERROR("copy %d cliprects failed: %d\n", args->num_cliprects, ret); + ret = -EFAULT; goto pre_mutex_err; } } @@ -3930,6 +3949,17 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) int ret; i915_verify_inactive(dev, __FILE__, __LINE__); + + if (obj_priv->gtt_space != NULL) { + if (alignment == 0) + alignment = i915_gem_get_gtt_alignment(obj); + if (obj_priv->gtt_offset & (alignment - 1)) { + ret = i915_gem_object_unbind(obj); + if (ret) + return ret; + } + } + if (obj_priv->gtt_space == NULL) { ret = i915_gem_object_bind_to_gtt(obj, alignment); if (ret) @@ -4669,6 +4699,16 @@ i915_gem_load(struct drm_device *dev) list_add(&dev_priv->mm.shrink_list, &shrink_list); spin_unlock(&shrink_list_lock); + /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ + if (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { + u32 tmp = I915_READ(MI_ARB_STATE); + if (!(tmp & MI_ARB_C3_LP_WRITE_ENABLE)) { + /* arb state is a masked write, so set bit + bit in mask */ + tmp = MI_ARB_C3_LP_WRITE_ENABLE | (MI_ARB_C3_LP_WRITE_ENABLE << MI_ARB_MASK_SHIFT); + I915_WRITE(MI_ARB_STATE, tmp); + } + } + /* Old X drivers will take 0-2 for front, back, depth buffers */ dev_priv->fence_reg_start = 3; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 200e398453ca..fb2811c58aff 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -353,21 +353,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) * reg, so dont bother to check the size */ if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) return false; - } else if (IS_I9XX(dev)) { - uint32_t pitch_val = ffs(stride / tile_width) - 1; - - /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB) - * instead of 4 (2KB) on 945s. - */ - if (pitch_val > I915_FENCE_MAX_PITCH_VAL || - size > (I830_FENCE_MAX_SIZE_VAL << 20)) + } else if (IS_I9XX(dev) || IS_I8XX(dev)) { + if (stride > 8192) return false; - } else { - uint32_t pitch_val = ffs(stride / tile_width) - 1; - if (pitch_val > I830_FENCE_MAX_PITCH_VAL || - size > (I830_FENCE_MAX_SIZE_VAL << 19)) - return false; + if (IS_I9XX(dev)) { + if (size > I830_FENCE_MAX_SIZE_VAL << 20) + return false; + } else { + if (size > I830_FENCE_MAX_SIZE_VAL << 19) + return false; + } } /* 965+ just needs multiples of tile width */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cc9b49ab1fd0..7214c852df99 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -214,7 +214,7 @@ #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) #define I830_FENCE_PITCH_SHIFT 4 #define I830_FENCE_REG_VALID (1<<0) -#define I915_FENCE_MAX_PITCH_VAL 0x10 +#define I915_FENCE_MAX_PITCH_VAL 4 #define I830_FENCE_MAX_PITCH_VAL 6 #define I830_FENCE_MAX_SIZE_VAL (1<<8) @@ -307,6 +307,70 @@ #define LM_BURST_LENGTH 0x00000700 #define LM_FIFO_WATERMARK 0x0000001F #define MI_ARB_STATE 0x020e4 /* 915+ only */ +#define MI_ARB_MASK_SHIFT 16 /* shift for enable bits */ + +/* Make render/texture TLB fetches lower priorty than associated data + * fetches. This is not turned on by default + */ +#define MI_ARB_RENDER_TLB_LOW_PRIORITY (1 << 15) + +/* Isoch request wait on GTT enable (Display A/B/C streams). + * Make isoch requests stall on the TLB update. May cause + * display underruns (test mode only) + */ +#define MI_ARB_ISOCH_WAIT_GTT (1 << 14) + +/* Block grant count for isoch requests when block count is + * set to a finite value. + */ +#define MI_ARB_BLOCK_GRANT_MASK (3 << 12) +#define MI_ARB_BLOCK_GRANT_8 (0 << 12) /* for 3 display planes */ +#define MI_ARB_BLOCK_GRANT_4 (1 << 12) /* for 2 display planes */ +#define MI_ARB_BLOCK_GRANT_2 (2 << 12) /* for 1 display plane */ +#define MI_ARB_BLOCK_GRANT_0 (3 << 12) /* don't use */ + +/* Enable render writes to complete in C2/C3/C4 power states. + * If this isn't enabled, render writes are prevented in low + * power states. That seems bad to me. + */ +#define MI_ARB_C3_LP_WRITE_ENABLE (1 << 11) + +/* This acknowledges an async flip immediately instead + * of waiting for 2TLB fetches. + */ +#define MI_ARB_ASYNC_FLIP_ACK_IMMEDIATE (1 << 10) + +/* Enables non-sequential data reads through arbiter + */ +#define MI_ARB_DUAL_DATA_PHASE_DISABLE (1 << 9) + +/* Disable FSB snooping of cacheable write cycles from binner/render + * command stream + */ +#define MI_ARB_CACHE_SNOOP_DISABLE (1 << 8) + +/* Arbiter time slice for non-isoch streams */ +#define MI_ARB_TIME_SLICE_MASK (7 << 5) +#define MI_ARB_TIME_SLICE_1 (0 << 5) +#define MI_ARB_TIME_SLICE_2 (1 << 5) +#define MI_ARB_TIME_SLICE_4 (2 << 5) +#define MI_ARB_TIME_SLICE_6 (3 << 5) +#define MI_ARB_TIME_SLICE_8 (4 << 5) +#define MI_ARB_TIME_SLICE_10 (5 << 5) +#define MI_ARB_TIME_SLICE_14 (6 << 5) +#define MI_ARB_TIME_SLICE_16 (7 << 5) + +/* Low priority grace period page size */ +#define MI_ARB_LOW_PRIORITY_GRACE_4KB (0 << 4) /* default */ +#define MI_ARB_LOW_PRIORITY_GRACE_8KB (1 << 4) + +/* Disable display A/B trickle feed */ +#define MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE (1 << 2) + +/* Set display plane priority */ +#define MI_ARB_DISPLAY_PRIORITY_A_B (0 << 0) /* display A > display B */ +#define MI_ARB_DISPLAY_PRIORITY_B_A (1 << 0) /* display B > display A */ + #define CACHE_MODE_0 0x02120 /* 915+ only */ #define CM0_MASK_SHIFT 16 #define CM0_IZ_OPT_DISABLE (1<<6) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 96cd256e60e6..d4b5b18f2f11 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -241,10 +241,6 @@ parse_general_definitions(struct drm_i915_private *dev_priv, GPIOF, }; - /* Set sensible defaults in case we can't find the general block - or it is the wrong chipset */ - dev_priv->crt_ddc_bus = -1; - general = find_section(bdb, BDB_GENERAL_DEFINITIONS); if (general) { u16 block_size = get_blocksize(general); @@ -366,6 +362,70 @@ parse_driver_features(struct drm_i915_private *dev_priv, dev_priv->render_reclock_avail = true; } +static void +parse_device_mapping(struct drm_i915_private *dev_priv, + struct bdb_header *bdb) +{ + struct bdb_general_definitions *p_defs; + struct child_device_config *p_child, *child_dev_ptr; + int i, child_device_num, count; + u16 block_size; + + p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); + if (!p_defs) { + DRM_DEBUG_KMS("No general definition block is found\n"); + return; + } + /* judge whether the size of child device meets the requirements. + * If the child device size obtained from general definition block + * is different with sizeof(struct child_device_config), skip the + * parsing of sdvo device info + */ + if (p_defs->child_dev_size != sizeof(*p_child)) { + /* different child dev size . Ignore it */ + DRM_DEBUG_KMS("different child size is found. Invalid.\n"); + return; + } + /* get the block size of general definitions */ + block_size = get_blocksize(p_defs); + /* get the number of child device */ + child_device_num = (block_size - sizeof(*p_defs)) / + sizeof(*p_child); + count = 0; + /* get the number of child device that is present */ + for (i = 0; i < child_device_num; i++) { + p_child = &(p_defs->devices[i]); + if (!p_child->device_type) { + /* skip the device block if device type is invalid */ + continue; + } + count++; + } + if (!count) { + DRM_DEBUG_KMS("no child dev is parsed from VBT \n"); + return; + } + dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); + if (!dev_priv->child_dev) { + DRM_DEBUG_KMS("No memory space for child device\n"); + return; + } + + dev_priv->child_dev_num = count; + count = 0; + for (i = 0; i < child_device_num; i++) { + p_child = &(p_defs->devices[i]); + if (!p_child->device_type) { + /* skip the device block if device type is invalid */ + continue; + } + child_dev_ptr = dev_priv->child_dev + count; + count++; + memcpy((void *)child_dev_ptr, (void *)p_child, + sizeof(*p_child)); + } + return; +} /** * intel_init_bios - initialize VBIOS settings & find VBT * @dev: DRM device @@ -417,6 +477,7 @@ intel_init_bios(struct drm_device *dev) parse_lfp_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); + parse_device_mapping(dev_priv, bdb); parse_driver_features(dev_priv, bdb); pci_unmap_rom(pdev, bios); diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 0f8e5f69ac7a..425ac9d7f724 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -549,4 +549,21 @@ bool intel_init_bios(struct drm_device *dev); #define SWF14_APM_STANDBY 0x1 #define SWF14_APM_RESTORE 0x0 +/* Add the device class for LFP, TV, HDMI */ +#define DEVICE_TYPE_INT_LFP 0x1022 +#define DEVICE_TYPE_INT_TV 0x1009 +#define DEVICE_TYPE_HDMI 0x60D2 +#define DEVICE_TYPE_DP 0x68C6 +#define DEVICE_TYPE_eDP 0x78C6 + +/* define the DVO port for HDMI output type */ +#define DVO_B 1 +#define DVO_C 2 +#define DVO_D 3 + +/* define the PORT for DP output type */ +#define PORT_IDPB 7 +#define PORT_IDPC 8 +#define PORT_IDPD 9 + #endif /* _I830_BIOS_H_ */ diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 5e730e6f8a74..166a24e76b21 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -557,7 +557,7 @@ void intel_crt_init(struct drm_device *dev) else { i2c_reg = GPIOA; /* Use VBT information for CRT DDC if available */ - if (dev_priv->crt_ddc_bus != -1) + if (dev_priv->crt_ddc_bus != 0) i2c_reg = dev_priv->crt_ddc_bus; } intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b00a1aaf0d71..79cc437af3b8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -785,8 +785,8 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, intel_clock_t clock; int max_n; bool found; - /* approximately equals target * 0.00488 */ - int err_most = (target >> 8) + (target >> 10); + /* approximately equals target * 0.00585 */ + int err_most = (target >> 8) + (target >> 9); found = false; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { @@ -1402,6 +1402,7 @@ static void igdng_enable_pll_edp (struct drm_crtc *crtc) dpa_ctl = I915_READ(DP_A); dpa_ctl |= DP_PLL_ENABLE; I915_WRITE(DP_A, dpa_ctl); + POSTING_READ(DP_A); udelay(200); } @@ -1953,6 +1954,9 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) int pipe = intel_crtc->pipe; bool enabled; + if (intel_crtc->dpms_mode == mode) + return; + dev_priv->display.dpms(crtc, mode); intel_crtc->dpms_mode = mode; @@ -3999,7 +4003,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) } intel_crtc->cursor_addr = 0; - intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; + intel_crtc->dpms_mode = -1; drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); intel_crtc->busy = false; @@ -4322,7 +4326,7 @@ static void intel_init_display(struct drm_device *dev) } /* Returns the core display clock speed */ - if (IS_I945G(dev)) + if (IS_I945G(dev) || (IS_G33(dev) && ! IS_IGDGM(dev))) dev_priv->display.get_display_clock_speed = i945_get_display_clock_speed; else if (IS_I915G(dev)) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 952bb4e2484d..d5b736104fd8 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -629,6 +629,13 @@ static const struct dmi_system_id bad_lid_status[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), }, }, + { + .ident = "Clevo M5x0N", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), + DMI_MATCH(DMI_BOARD_NAME, "M5x0N"), + }, + }, { } }; @@ -641,8 +648,12 @@ static const struct dmi_system_id bad_lid_status[] = { */ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) { + struct drm_device *dev = connector->dev; enum drm_connector_status status = connector_status_connected; + if (IS_I8XX(dev)) + return connector_status_connected; + if (!acpi_lid_open() && !dmi_check_system(bad_lid_status)) status = connector_status_disconnected; @@ -878,68 +889,57 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Clientron U800", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), + DMI_MATCH(DMI_PRODUCT_NAME, "U800"), + }, + }, { } /* terminating entry */ }; -#ifdef CONFIG_ACPI /* - * check_lid_device -- check whether @handle is an ACPI LID device. - * @handle: ACPI device handle - * @level : depth in the ACPI namespace tree - * @context: the number of LID device when we find the device - * @rv: a return value to fill if desired (Not use) + * Enumerate the child dev array parsed from VBT to check whether + * the LVDS is present. + * If it is present, return 1. + * If it is not present, return false. + * If no child dev is parsed from VBT, it assumes that the LVDS is present. + * Note: The addin_offset should also be checked for LVDS panel. + * Only when it is non-zero, it is assumed that it is present. */ -static acpi_status -check_lid_device(acpi_handle handle, u32 level, void *context, - void **return_value) +static int lvds_is_present_in_vbt(struct drm_device *dev) { - struct acpi_device *acpi_dev; - int *lid_present = context; + struct drm_i915_private *dev_priv = dev->dev_private; + struct child_device_config *p_child; + int i, ret; - acpi_dev = NULL; - /* Get the acpi device for device handle */ - if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { - /* If there is no ACPI device for handle, return */ - return AE_OK; - } - - if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) - *lid_present = 1; - - return AE_OK; -} - -/** - * check whether there exists the ACPI LID device by enumerating the ACPI - * device tree. - */ -static int intel_lid_present(void) -{ - int lid_present = 0; - - if (acpi_disabled) { - /* If ACPI is disabled, there is no ACPI device tree to - * check, so assume the LID device would have been present. - */ + if (!dev_priv->child_dev_num) return 1; + + ret = 0; + for (i = 0; i < dev_priv->child_dev_num; i++) { + p_child = dev_priv->child_dev + i; + /* + * If the device type is not LFP, continue. + * If the device type is 0x22, it is also regarded as LFP. + */ + if (p_child->device_type != DEVICE_TYPE_INT_LFP && + p_child->device_type != DEVICE_TYPE_LFP) + continue; + + /* The addin_offset should be checked. Only when it is + * non-zero, it is regarded as present. + */ + if (p_child->addin_offset) { + ret = 1; + break; + } } - - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - check_lid_device, &lid_present, NULL); - - return lid_present; + return ret; } -#else -static int intel_lid_present(void) -{ - /* In the absence of ACPI built in, assume that the LID device would - * have been present. - */ - return 1; -} -#endif /** * intel_lvds_init - setup LVDS connectors on this device @@ -964,15 +964,10 @@ void intel_lvds_init(struct drm_device *dev) if (dmi_check_system(intel_no_lvds)) return; - /* Assume that any device without an ACPI LID device also doesn't - * have an integrated LVDS. We would be better off parsing the BIOS - * to get a reliable indicator, but that code isn't written yet. - * - * In the case of all-in-one desktops using LVDS that we've seen, - * they're using SDVO LVDS. - */ - if (!intel_lid_present()) + if (!lvds_is_present_in_vbt(dev)) { + DRM_DEBUG_KMS("LVDS is not present in VBT\n"); return; + } if (IS_IGDNG(dev)) { if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 3f5aaf14e6a3..5d9c6a7a6ed5 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -35,6 +35,7 @@ #include "i915_drm.h" #include "i915_drv.h" #include "intel_sdvo_regs.h" +#include #undef SDVO_DEBUG @@ -2289,6 +2290,25 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) return 0x72; } +static int intel_sdvo_bad_tv_callback(const struct dmi_system_id *id) +{ + DRM_DEBUG_KMS("Ignoring bad SDVO TV connector for %s\n", id->ident); + return 1; +} + +static struct dmi_system_id intel_sdvo_bad_tv[] = { + { + .callback = intel_sdvo_bad_tv_callback, + .ident = "IntelG45/ICH10R/DME1737", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM CORPORATION"), + DMI_MATCH(DMI_PRODUCT_NAME, "4800784"), + }, + }, + + { } /* terminating entry */ +}; + static bool intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) { @@ -2329,7 +2349,8 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); } - } else if (flags & SDVO_OUTPUT_SVID0) { + } else if ((flags & SDVO_OUTPUT_SVID0) && + !dmi_check_system(intel_sdvo_bad_tv)) { sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index ce026f002ea5..5b28b4e7ebe7 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1801,8 +1801,6 @@ intel_tv_init(struct drm_device *dev) drm_connector_attach_property(connector, dev->mode_config.tv_bottom_margin_property, tv_priv->margin[TV_MARGIN_BOTTOM]); - - dev_priv->hotplug_supported_mask |= TV_HOTPLUG_INT_STATUS; out: drm_sysfs_connector_add(connector); } diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index eb740fc3549f..ccf42c3dd1be 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -368,6 +368,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, /* 2D, 3D, CUBE */ switch (tmp) { case 0: + case 3: + case 4: case 5: case 6: case 7: diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 2f43ee8e4048..d8c4f72eef8e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -346,11 +346,12 @@ void r300_gpu_init(struct radeon_device *rdev) r100_hdp_reset(rdev); /* FIXME: rv380 one pipes ? */ - if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) { + if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || + (rdev->family == CHIP_R350)) { /* r300,r350 */ rdev->num_gb_pipes = 2; } else { - /* rv350,rv370,rv380 */ + /* rv350,rv370,rv380,r300 AD */ rdev->num_gb_pipes = 1; } rdev->num_z_pipes = 1; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 278f646bc18e..731047301de4 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1686,13 +1686,14 @@ int r600_init(struct radeon_device *rdev) if (rdev->accel_working) { r = radeon_ib_pool_init(rdev); if (r) { - DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); - rdev->accel_working = false; - } - r = r600_ib_test(rdev); - if (r) { - DRM_ERROR("radeon: failled testing IB (%d).\n", r); + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); rdev->accel_working = false; + } else { + r = r600_ib_test(rdev); + if (r) { + dev_err(rdev->dev, "IB test failed (%d).\n", r); + rdev->accel_working = false; + } } } return 0; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0d820764f340..838b88c14f57 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -36,6 +36,10 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; +struct r600_cs_track { + u32 cb_color0_base_last; +}; + /** * r600_cs_packet_parse() - parse cp packet and point ib index to next packet * @parser: parser structure holding parsing context. @@ -176,6 +180,28 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, return 0; } +/** + * r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc + * @parser: parser structure holding parsing context. + * + * Check next packet is relocation packet3, do bo validation and compute + * GPU offset using the provided start. + **/ +static inline int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) +{ + struct radeon_cs_packet p3reloc; + int r; + + r = r600_cs_packet_parse(p, &p3reloc, p->idx); + if (r) { + return 0; + } + if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { + return 0; + } + return 1; +} + /** * r600_cs_packet_next_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. @@ -337,6 +363,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { struct radeon_cs_reloc *reloc; + struct r600_cs_track *track; volatile u32 *ib; unsigned idx; unsigned i; @@ -344,6 +371,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, int r; u32 idx_value; + track = (struct r600_cs_track *)p->track; ib = p->ib->ptr; idx = pkt->idx + 1; idx_value = radeon_get_ib_value(p, idx); @@ -503,9 +531,60 @@ static int r600_packet3_check(struct radeon_cs_parser *p, for (i = 0; i < pkt->count; i++) { reg = start_reg + (4 * i); switch (reg) { + /* This register were added late, there is userspace + * which does provide relocation for those but set + * 0 offset. In order to avoid breaking old userspace + * we detect this and set address to point to last + * CB_COLOR0_BASE, note that if userspace doesn't set + * CB_COLOR0_BASE before this register we will report + * error. Old userspace always set CB_COLOR0_BASE + * before any of this. + */ + case R_0280E0_CB_COLOR0_FRAG: + case R_0280E4_CB_COLOR1_FRAG: + case R_0280E8_CB_COLOR2_FRAG: + case R_0280EC_CB_COLOR3_FRAG: + case R_0280F0_CB_COLOR4_FRAG: + case R_0280F4_CB_COLOR5_FRAG: + case R_0280F8_CB_COLOR6_FRAG: + case R_0280FC_CB_COLOR7_FRAG: + case R_0280C0_CB_COLOR0_TILE: + case R_0280C4_CB_COLOR1_TILE: + case R_0280C8_CB_COLOR2_TILE: + case R_0280CC_CB_COLOR3_TILE: + case R_0280D0_CB_COLOR4_TILE: + case R_0280D4_CB_COLOR5_TILE: + case R_0280D8_CB_COLOR6_TILE: + case R_0280DC_CB_COLOR7_TILE: + if (!r600_cs_packet_next_is_pkt3_nop(p)) { + if (!track->cb_color0_base_last) { + dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); + return -EINVAL; + } + ib[idx+1+i] = track->cb_color0_base_last; + printk_once(KERN_WARNING "You have old & broken userspace " + "please consider updating mesa & xf86-video-ati\n"); + } else { + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); + return -EINVAL; + } + ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + } + break; case DB_DEPTH_BASE: case DB_HTILE_DATA_BASE: case CB_COLOR0_BASE: + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->cb_color0_base_last = ib[idx+1+i]; + break; case CB_COLOR1_BASE: case CB_COLOR2_BASE: case CB_COLOR3_BASE: @@ -678,8 +757,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p, int r600_cs_parse(struct radeon_cs_parser *p) { struct radeon_cs_packet pkt; + struct r600_cs_track *track; int r; + track = kzalloc(sizeof(*track), GFP_KERNEL); + p->track = track; do { r = r600_cs_packet_parse(p, &pkt, p->idx); if (r) { @@ -757,6 +839,7 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, /* initialize parser */ memset(&parser, 0, sizeof(struct radeon_cs_parser)); parser.filp = filp; + parser.dev = &dev->pdev->dev; parser.rdev = NULL; parser.family = family; parser.ib = &fake_ib; diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 27ab428b149b..56fc6589132e 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -674,4 +674,30 @@ #define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16) #define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) +#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 + +#define R_0280E0_CB_COLOR0_FRAG 0x0280E0 +#define S_0280E0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) +#define G_0280E0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_0280E0_BASE_256B 0x00000000 +#define R_0280E4_CB_COLOR1_FRAG 0x0280E4 +#define R_0280E8_CB_COLOR2_FRAG 0x0280E8 +#define R_0280EC_CB_COLOR3_FRAG 0x0280EC +#define R_0280F0_CB_COLOR4_FRAG 0x0280F0 +#define R_0280F4_CB_COLOR5_FRAG 0x0280F4 +#define R_0280F8_CB_COLOR6_FRAG 0x0280F8 +#define R_0280FC_CB_COLOR7_FRAG 0x0280FC +#define R_0280C0_CB_COLOR0_TILE 0x0280C0 +#define S_0280C0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) +#define G_0280C0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_0280C0_BASE_256B 0x00000000 +#define R_0280C4_CB_COLOR1_TILE 0x0280C4 +#define R_0280C8_CB_COLOR2_TILE 0x0280C8 +#define R_0280CC_CB_COLOR3_TILE 0x0280CC +#define R_0280D0_CB_COLOR4_TILE 0x0280D0 +#define R_0280D4_CB_COLOR5_TILE 0x0280D4 +#define R_0280D8_CB_COLOR6_TILE 0x0280D8 +#define R_0280DC_CB_COLOR7_TILE 0x0280DC + + #endif diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 224506a2f7b1..6735213892d5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -448,6 +448,7 @@ struct radeon_cs_chunk { }; struct radeon_cs_parser { + struct device *dev; struct radeon_device *rdev; struct drm_file *filp; /* chunks */ diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 969502acc29c..e5e22b1cf502 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -161,6 +161,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, } } + /* ASUS HD 3600 board lists the DVI port as HDMI */ + if ((dev->pdev->device == 0x9598) && + (dev->pdev->subsystem_vendor == 0x1043) && + (dev->pdev->subsystem_device == 0x01e4)) { + if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { + *connector_type = DRM_MODE_CONNECTOR_DVII; + } + } + /* ASUS HD 3450 board lists the DVI port as HDMI */ if ((dev->pdev->device == 0x95C5) && (dev->pdev->subsystem_vendor == 0x1043) && @@ -942,7 +951,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct lvds->native_mode.vtotal = lvds->native_mode.vdisplay + le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + - le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); + le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); lvds->panel_pwr_delay = diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 29763ceae3af..b1dc1a112aef 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -140,12 +140,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, { struct drm_device *dev = connector->dev; struct drm_connector *conflict; + struct radeon_connector *radeon_conflict; int i; list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { if (conflict == connector) continue; + radeon_conflict = to_radeon_connector(conflict); for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (conflict->encoder_ids[i] == 0) break; @@ -155,6 +157,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, if (conflict->status != connector_status_connected) continue; + if (radeon_conflict->use_digital) + continue; + if (priority == true) { DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); @@ -281,7 +286,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr radeon_encoder = to_radeon_encoder(encoder); if (!radeon_encoder->enc_priv) return 0; - if (rdev->is_atom_bios) { + if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) { struct radeon_encoder_atom_dac *dac_int; dac_int = radeon_encoder->enc_priv; dac_int->tv_std = val; diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 4f7afc79dd82..c7236f4c6cdd 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -417,8 +417,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) return -EBUSY; } -static void radeon_init_pipes(drm_radeon_private_t *dev_priv) +static void radeon_init_pipes(struct drm_device *dev) { + drm_radeon_private_t *dev_priv = dev->dev_private; uint32_t gb_tile_config, gb_pipe_sel = 0; if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { @@ -436,11 +437,12 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; } else { /* R3xx */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 && + dev->pdev->device != 0x4144) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) { dev_priv->num_gb_pipes = 2; } else { - /* R3Vxx */ + /* RV3xx/R300 AD */ dev_priv->num_gb_pipes = 1; } } @@ -736,7 +738,7 @@ static int radeon_do_engine_reset(struct drm_device * dev) /* setup the raster pipes */ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300) - radeon_init_pipes(dev_priv); + radeon_init_pipes(dev); /* Reset the CP ring */ radeon_do_cp_reset(dev_priv); @@ -1644,6 +1646,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri radeon_cp_load_microcode(dev_priv); radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); + dev_priv->have_z_offset = 0; radeon_do_engine_reset(dev); radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 5ab2cf96a264..20c52da0f62f 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -230,6 +230,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) memset(&parser, 0, sizeof(struct radeon_cs_parser)); parser.filp = filp; parser.rdev = rdev; + parser.dev = rdev->dev; r = radeon_cs_parser_init(&parser, data); if (r) { DRM_ERROR("Failed to initialize parser !\n"); @@ -246,7 +247,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } r = radeon_cs_parser_relocs(&parser); if (r) { - DRM_ERROR("Failed to parse relocation !\n"); + if (r != -ERESTARTSYS) + DRM_ERROR("Failed to parse relocation %d!\n", r); radeon_cs_parser_fini(&parser, r); mutex_unlock(&rdev->cs_mutex); return r; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index c85df4afcb7a..6f683159fc64 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -599,7 +599,11 @@ radeon_user_framebuffer_create(struct drm_device *dev, struct drm_gem_object *obj; obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); - + if (obj == NULL) { + dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " + "can't create framebuffer\n", mode_cmd->handle); + return NULL; + } return radeon_framebuffer_create(dev, mode_cmd, obj); } diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 350962e0f346..76e4070388c6 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -267,6 +267,8 @@ typedef struct drm_radeon_private { u32 scratch_ages[5]; + int have_z_offset; + /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ resource_size_t fb_aper_offset; diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index d42bc512d75a..4478b994b500 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1155,8 +1155,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, case ENCODER_OBJECT_ID_INTERNAL_DAC2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: atombios_dac_setup(encoder, ATOM_ENABLE); - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) - atombios_tv_setup(encoder, ATOM_ENABLE); + if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { + if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) + atombios_tv_setup(encoder, ATOM_ENABLE); + else + atombios_tv_setup(encoder, ATOM_DISABLE); + } break; } atombios_apply_encoder_quirks(encoder, adjusted_mode); diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 22ce4d6015e8..7547ec6418bb 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -261,7 +261,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, if (!ref_div) return 1; - vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div; + vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div; /* * This is horribly crude: the VCO frequency range is divided into diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 00382122869b..183bef831afb 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -89,6 +89,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) udelay(panel_pwr_delay * 1000); WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); + udelay(panel_pwr_delay * 1000); break; } diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c index 3a12bb0c0563..fc64a20b8583 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c @@ -57,6 +57,10 @@ #define NTSC_TV_PLL_N_14 693 #define NTSC_TV_PLL_P_14 7 +#define PAL_TV_PLL_M_14 19 +#define PAL_TV_PLL_N_14 353 +#define PAL_TV_PLL_P_14 5 + #define VERT_LEAD_IN_LINES 2 #define FRAC_BITS 0xe #define FRAC_MASK 0x3fff @@ -205,9 +209,24 @@ static const struct radeon_tv_mode_constants available_tv_modes[] = { 630627, /* defRestart */ 347, /* crtcPLL_N */ 14, /* crtcPLL_M */ - 8, /* crtcPLL_postDiv */ + 8, /* crtcPLL_postDiv */ 1022, /* pixToTV */ }, + { /* PAL timing for 14 Mhz ref clk */ + 800, /* horResolution */ + 600, /* verResolution */ + TV_STD_PAL, /* standard */ + 1131, /* horTotal */ + 742, /* verTotal */ + 813, /* horStart */ + 840, /* horSyncStart */ + 633, /* verSyncStart */ + 708369, /* defRestart */ + 211, /* crtcPLL_N */ + 9, /* crtcPLL_M */ + 8, /* crtcPLL_postDiv */ + 759, /* pixToTV */ + }, }; #define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes) @@ -242,7 +261,7 @@ static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(stru if (pll->reference_freq == 2700) const_ptr = &available_tv_modes[1]; else - const_ptr = &available_tv_modes[1]; /* FIX ME */ + const_ptr = &available_tv_modes[3]; } return const_ptr; } @@ -685,9 +704,9 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, n = PAL_TV_PLL_N_27; p = PAL_TV_PLL_P_27; } else { - m = PAL_TV_PLL_M_27; - n = PAL_TV_PLL_N_27; - p = PAL_TV_PLL_P_27; + m = PAL_TV_PLL_M_14; + n = PAL_TV_PLL_N_14; + p = PAL_TV_PLL_P_14; } } diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 38537d971a3e..474791076cf9 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -101,6 +101,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * DRM_ERROR("Invalid depth buffer offset\n"); return -EINVAL; } + dev_priv->have_z_offset = 1; break; case RADEON_EMIT_PP_CNTL: @@ -876,6 +877,12 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, if (tmp & RADEON_BACK) flags |= RADEON_FRONT; } + if (flags & (RADEON_DEPTH|RADEON_STENCIL)) { + if (!dev_priv->have_z_offset) { + printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n"); + flags &= ~(RADEON_DEPTH | RADEON_STENCIL); + } + } if (flags & (RADEON_FRONT | RADEON_BACK)) { diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 4444f48c496e..170029747daf 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -57,7 +57,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev) WREG32_MC(R_000100_MC_PT0_CNTL, tmp); tmp = RREG32_MC(R_000100_MC_PT0_CNTL); - tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1); + tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1); WREG32_MC(R_000100_MC_PT0_CNTL, tmp); tmp = RREG32_MC(R_000100_MC_PT0_CNTL); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b0efd0ddae7a..c42403b0827c 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1034,13 +1034,14 @@ int rv770_init(struct radeon_device *rdev) if (rdev->accel_working) { r = radeon_ib_pool_init(rdev); if (r) { - DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); - rdev->accel_working = false; - } - r = r600_ib_test(rdev); - if (r) { - DRM_ERROR("radeon: failled testing IB (%d).\n", r); + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); rdev->accel_working = false; + } else { + r = r600_ib_test(rdev); + if (r) { + dev_err(rdev->dev, "IB test failed (%d).\n", r); + rdev->accel_working = false; + } } } return 0; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index c70927ecda21..8cb88e7e0302 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -330,6 +330,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, INIT_LIST_HEAD(&fbo->lru); INIT_LIST_HEAD(&fbo->swap); fbo->vm_node = NULL; + atomic_set(&fbo->cpu_writers, 0); fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); if (fbo->mem.mm_node) diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 7bcb89f39ce8..3d5b8b0705de 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -466,7 +466,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) void *from_virtual; void *to_virtual; int i; - int ret; + int ret = -ENOMEM; if (ttm->page_flags & TTM_PAGE_FLAG_USER) { ret = ttm_tt_set_user(ttm, ttm->tsk, ttm->start, @@ -485,8 +485,10 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) for (i = 0; i < ttm->num_pages; ++i) { from_page = read_mapping_page(swap_space, i, NULL); - if (IS_ERR(from_page)) + if (IS_ERR(from_page)) { + ret = PTR_ERR(from_page); goto out_err; + } to_page = __ttm_tt_get_page(ttm, i); if (unlikely(to_page == NULL)) goto out_err; @@ -509,7 +511,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) return 0; out_err: ttm_tt_free_alloced_pages(ttm); - return -ENOMEM; + return ret; } int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) @@ -521,6 +523,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) void *from_virtual; void *to_virtual; int i; + int ret = -ENOMEM; BUG_ON(ttm->state != tt_unbound && ttm->state != tt_unpopulated); BUG_ON(ttm->caching_state != tt_cached); @@ -543,7 +546,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) 0); if (unlikely(IS_ERR(swap_storage))) { printk(KERN_ERR "Failed allocating swap storage.\n"); - return -ENOMEM; + return PTR_ERR(swap_storage); } } else swap_storage = persistant_swap_storage; @@ -555,9 +558,10 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) if (unlikely(from_page == NULL)) continue; to_page = read_mapping_page(swap_space, i, NULL); - if (unlikely(to_page == NULL)) + if (unlikely(IS_ERR(to_page))) { + ret = PTR_ERR(to_page); goto out_err; - + } preempt_disable(); from_virtual = kmap_atomic(from_page, KM_USER0); to_virtual = kmap_atomic(to_page, KM_USER1); @@ -581,5 +585,5 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) if (!persistant_swap_storage) fput(swap_storage); - return -ENOMEM; + return ret; } diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 1ac0c93603c9..aa8688d25e84 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -954,6 +954,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, } } else if (strncmp(curr_pos, "target ", 7) == 0) { + struct pci_bus *pbus; unsigned int domain, bus, devfn; struct vga_device *vgadev; @@ -961,7 +962,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, remaining -= 7; pr_devel("client 0x%p called 'target'\n", priv); /* if target is default */ - if (!strncmp(buf, "default", 7)) + if (!strncmp(curr_pos, "default", 7)) pdev = pci_dev_get(vga_default_device()); else { if (!vga_pci_str_to_vars(curr_pos, remaining, @@ -969,18 +970,31 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, ret_val = -EPROTO; goto done; } + pr_devel("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos, + domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); - pdev = pci_get_bus_and_slot(bus, devfn); + pbus = pci_find_bus(domain, bus); + pr_devel("vgaarb: pbus %p\n", pbus); + if (pbus == NULL) { + pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n", + domain, bus); + ret_val = -ENODEV; + goto done; + } + pdev = pci_get_slot(pbus, devfn); + pr_devel("vgaarb: pdev %p\n", pdev); if (!pdev) { - pr_info("vgaarb: invalid PCI address!\n"); + pr_err("vgaarb: invalid PCI address %x:%x\n", + bus, devfn); ret_val = -ENODEV; goto done; } } vgadev = vgadev_find(pdev); + pr_devel("vgaarb: vgadev %p\n", vgadev); if (vgadev == NULL) { - pr_info("vgaarb: this pci device is not a vga device\n"); + pr_err("vgaarb: this pci device is not a vga device\n"); pci_dev_put(pdev); ret_val = -ENODEV; goto done; @@ -998,7 +1012,8 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, } } if (i == MAX_USER_CARDS) { - pr_err("vgaarb: maximum user cards number reached!\n"); + pr_err("vgaarb: maximum user cards (%d) number reached!\n", + MAX_USER_CARDS); pci_dev_put(pdev); /* XXX: which value to return? */ ret_val = -ENOMEM; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 96783542f7f5..15978635d34f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1306,6 +1306,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, @@ -1658,8 +1659,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, - { 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_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) }, diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c index cab13e8c7d29..3975e039c3dd 100644 --- a/drivers/hid/hid-gyration.c +++ b/drivers/hid/hid-gyration.c @@ -53,10 +53,13 @@ static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi, static int gyration_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { - struct input_dev *input = field->hidinput->input; + + if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput) + return 0; if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK && (usage->hid & 0xff) == 0x82) { + struct input_dev *input = field->hidinput->input; input_event(input, usage->type, usage->code, 1); input_sync(input); input_event(input, usage->type, usage->code, 0); @@ -70,6 +73,7 @@ static int gyration_event(struct hid_device *hdev, struct hid_field *field, static const struct hid_device_id gyration_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { } }; MODULE_DEVICE_TABLE(hid, gyration_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e380e7bee8c1..252853d4dbe3 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -251,6 +251,7 @@ #define USB_VENDOR_ID_GYRATION 0x0c16 #define USB_DEVICE_ID_GYRATION_REMOTE 0x0002 #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 +#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 #define USB_VENDOR_ID_HAPP 0x078b #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 @@ -349,6 +350,9 @@ #define USB_VENDOR_ID_NEC 0x073e #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 +#define USB_VENDOR_ID_NEXTWINDOW 0x1926 +#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 + #define USB_VENDOR_ID_NTRIG 0x1b96 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 @@ -392,10 +396,6 @@ #define USB_VENDOR_ID_SUNPLUS 0x04fc #define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 -#define USB_VENDOR_ID_TENX 0x1130 -#define USB_DEVICE_ID_TENX_IBUDDY1 0x0001 -#define USB_DEVICE_ID_TENX_IBUDDY2 0x0002 - #define USB_VENDOR_ID_THRUSTMASTER 0x044f #define USB_VENDOR_ID_TOPMAX 0x0663 diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index cdd136942bca..66579c0bf328 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -105,11 +105,15 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { unsigned int minor = iminor(file->f_path.dentry->d_inode); - /* FIXME: What stops hidraw_table going NULL */ - struct hid_device *dev = hidraw_table[minor]->hid; + struct hid_device *dev; __u8 *buf; int ret = 0; + if (!hidraw_table[minor]) + return -ENODEV; + + dev = hidraw_table[minor]->hid; + if (!dev->hid_output_raw_report) return -ENODEV; @@ -237,11 +241,16 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, struct inode *inode = file->f_path.dentry->d_inode; unsigned int minor = iminor(inode); long ret = 0; - /* FIXME: What stops hidraw_table going NULL */ - struct hidraw *dev = hidraw_table[minor]; + struct hidraw *dev; void __user *user_arg = (void __user*) arg; lock_kernel(); + dev = hidraw_table[minor]; + if (!dev) { + ret = -ENODEV; + goto out; + } + switch (cmd) { case HIDIOCGRDESCSIZE: if (put_user(dev->hid->rsize, (int __user *)arg)) @@ -314,6 +323,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, ret = -ENOTTY; } +out: unlock_kernel(); return ret; } diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 5d901f698838..e9add5b3481d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -318,6 +318,7 @@ static int hid_submit_out(struct hid_device *hid) err_hid("usb_submit_urb(out) failed"); return -1; } + usbhid->last_out = jiffies; } else { /* * queue work to wake up the device. @@ -379,6 +380,7 @@ static int hid_submit_ctrl(struct hid_device *hid) err_hid("usb_submit_urb(ctrl) failed"); return -1; } + usbhid->last_ctrl = jiffies; } else { /* * queue work to wake up the device. @@ -514,9 +516,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re usbhid->out[usbhid->outhead].report = report; usbhid->outhead = head; - if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) + if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) { if (hid_submit_out(hid)) clear_bit(HID_OUT_RUNNING, &usbhid->iofl); + } else { + /* + * the queue is known to run + * but an earlier request may be stuck + * we may need to time out + * no race because this is called under + * spinlock + */ + if (time_after(jiffies, usbhid->last_out + HZ * 5)) + usb_unlink_urb(usbhid->urbout); + } return; } @@ -537,9 +550,20 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re usbhid->ctrl[usbhid->ctrlhead].dir = dir; usbhid->ctrlhead = head; - if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) + if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) { if (hid_submit_ctrl(hid)) clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); + } else { + /* + * the queue is known to run + * but an earlier request may be stuck + * we may need to time out + * no race because this is called under + * spinlock + */ + if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) + usb_unlink_urb(usbhid->urbctrl); + } } void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) @@ -976,16 +1000,6 @@ static int usbhid_start(struct hid_device *hid) } } - init_waitqueue_head(&usbhid->wait); - INIT_WORK(&usbhid->reset_work, hid_reset); - INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); - setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); - - spin_lock_init(&usbhid->lock); - - usbhid->intf = intf; - usbhid->ifnum = interface->desc.bInterfaceNumber; - usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); if (!usbhid->urbctrl) { ret = -ENOMEM; @@ -1156,6 +1170,14 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * hid->driver_data = usbhid; usbhid->hid = hid; + usbhid->intf = intf; + usbhid->ifnum = interface->desc.bInterfaceNumber; + + init_waitqueue_head(&usbhid->wait); + INIT_WORK(&usbhid->reset_work, hid_reset); + INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); + setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); + spin_lock_init(&usbhid->lock); ret = hid_add_device(hid); if (ret) { diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 5713b93e76cb..64c5dee27106 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -37,6 +37,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, + { USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT}, { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 08f505ca2e3d..ec20400c7f29 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -80,12 +80,14 @@ struct usbhid_device { unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ char *ctrlbuf; /* Control buffer */ dma_addr_t ctrlbuf_dma; /* Control buffer dma */ + unsigned long last_ctrl; /* record of last output for timeouts */ struct urb *urbout; /* Output URB */ struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ unsigned char outhead, outtail; /* Output pipe fifo head & tail */ char *outbuf; /* Output buffer */ dma_addr_t outbuf_dma; /* Output buffer dma */ + unsigned long last_out; /* record of last output for timeouts */ spinlock_t lock; /* fifo spinlock */ unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c index 6c9ace1b76f6..2ad62c339cd2 100644 --- a/drivers/hwmon/ams/ams-core.c +++ b/drivers/hwmon/ams/ams-core.c @@ -213,7 +213,7 @@ int __init ams_init(void) return -ENODEV; } -void ams_exit(void) +void ams_sensor_detach(void) { /* Remove input device */ ams_input_exit(); @@ -221,9 +221,6 @@ void ams_exit(void) /* Remove attributes */ device_remove_file(&ams_info.of_dev->dev, &dev_attr_current); - /* Shut down implementation */ - ams_info.exit(); - /* Flush interrupt worker * * We do this after ams_info.exit(), because an interrupt might @@ -239,6 +236,12 @@ void ams_exit(void) pmf_unregister_irq_client(&ams_freefall_client); } +static void __exit ams_exit(void) +{ + /* Shut down implementation */ + ams_info.exit(); +} + MODULE_AUTHOR("Stelian Pop, Michael Hanselmann"); MODULE_DESCRIPTION("Apple Motion Sensor driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c index 2cbf8a6506c7..abeecd27b484 100644 --- a/drivers/hwmon/ams/ams-i2c.c +++ b/drivers/hwmon/ams/ams-i2c.c @@ -238,6 +238,8 @@ static int ams_i2c_probe(struct i2c_client *client, static int ams_i2c_remove(struct i2c_client *client) { if (ams_info.has_device) { + ams_sensor_detach(); + /* Disable interrupts */ ams_i2c_set_irq(AMS_IRQ_ALL, 0); diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c index fb18b3d3162b..4f61b3ee1b08 100644 --- a/drivers/hwmon/ams/ams-pmu.c +++ b/drivers/hwmon/ams/ams-pmu.c @@ -133,6 +133,8 @@ static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z) static void ams_pmu_exit(void) { + ams_sensor_detach(); + /* Disable interrupts */ ams_pmu_set_irq(AMS_IRQ_ALL, 0); diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h index 5ed387b0bd9a..b28d7e27a031 100644 --- a/drivers/hwmon/ams/ams.h +++ b/drivers/hwmon/ams/ams.h @@ -61,6 +61,7 @@ extern struct ams ams_info; extern void ams_sensors(s8 *x, s8 *y, s8 *z); extern int ams_sensor_attach(void); +extern void ams_sensor_detach(void); extern int ams_pmu_init(struct device_node *np); extern int ams_i2c_init(struct device_node *np); diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 2d7bceeed0bc..585219167fa7 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -53,6 +53,7 @@ struct coretemp_data { struct mutex update_lock; const char *name; u32 id; + u16 core_id; char valid; /* zero until following fields are valid */ unsigned long last_updated; /* in jiffies */ int temp; @@ -75,7 +76,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute if (attr->index == SHOW_NAME) ret = sprintf(buf, "%s\n", data->name); else /* show label */ - ret = sprintf(buf, "Core %d\n", data->id); + ret = sprintf(buf, "Core %d\n", data->core_id); return ret; } @@ -228,7 +229,7 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * if (err) { dev_warn(dev, "Unable to access MSR 0xEE, for Tjmax, left" - " at default"); + " at default\n"); } else if (eax & 0x40000000) { tjmax = tjmax_ee; } @@ -255,6 +256,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev) } data->id = pdev->id; +#ifdef CONFIG_SMP + data->core_id = c->cpu_core_id; +#endif data->name = "coretemp"; mutex_init(&data->update_lock); @@ -352,6 +356,10 @@ struct pdev_entry { struct list_head list; struct platform_device *pdev; unsigned int cpu; +#ifdef CONFIG_SMP + u16 phys_proc_id; + u16 cpu_core_id; +#endif }; static LIST_HEAD(pdev_list); @@ -362,6 +370,22 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) int err; struct platform_device *pdev; struct pdev_entry *pdev_entry; +#ifdef CONFIG_SMP + struct cpuinfo_x86 *c = &cpu_data(cpu); +#endif + + mutex_lock(&pdev_list_mutex); + +#ifdef CONFIG_SMP + /* Skip second HT entry of each core */ + list_for_each_entry(pdev_entry, &pdev_list, list) { + if (c->phys_proc_id == pdev_entry->phys_proc_id && + c->cpu_core_id == pdev_entry->cpu_core_id) { + err = 0; /* Not an error */ + goto exit; + } + } +#endif pdev = platform_device_alloc(DRVNAME, cpu); if (!pdev) { @@ -385,7 +409,10 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) pdev_entry->pdev = pdev; pdev_entry->cpu = cpu; - mutex_lock(&pdev_list_mutex); +#ifdef CONFIG_SMP + pdev_entry->phys_proc_id = c->phys_proc_id; + pdev_entry->cpu_core_id = c->cpu_core_id; +#endif list_add_tail(&pdev_entry->list, &pdev_list); mutex_unlock(&pdev_list_mutex); @@ -396,6 +423,7 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) exit_device_put: platform_device_put(pdev); exit: + mutex_unlock(&pdev_list_mutex); return err; } diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index e2107e533ede..afebc3439881 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -79,7 +79,7 @@ I2C_CLIENT_INSMOD_2(f75373, f75375); #define F75375_REG_PWM2_DROP_DUTY 0x6C #define FAN_CTRL_LINEAR(nr) (4 + nr) -#define FAN_CTRL_MODE(nr) (5 + ((nr) * 2)) +#define FAN_CTRL_MODE(nr) (4 + ((nr) * 2)) /* * Data structures and manipulation thereof @@ -298,7 +298,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) return -EINVAL; fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); - fanmode = ~(3 << FAN_CTRL_MODE(nr)); + fanmode &= ~(3 << FAN_CTRL_MODE(nr)); switch (val) { case 0: /* Full speed */ @@ -350,7 +350,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); conf = f75375_read8(client, F75375_REG_CONFIG1); - conf = ~(1 << FAN_CTRL_LINEAR(nr)); + conf &= ~(1 << FAN_CTRL_LINEAR(nr)); if (val == 0) conf |= (1 << FAN_CTRL_LINEAR(nr)) ; diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index be475e844c2a..f16d60f0bf47 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c @@ -324,8 +324,8 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) lis3lv02d_joystick_disable(); lis3lv02d_poweroff(&lis3_dev); - flush_work(&hpled_led.work); led_classdev_unregister(&hpled_led.led_classdev); + flush_work(&hpled_led.work); return lis3lv02d_remove_fs(&lis3_dev); } diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index a3749cb0f181..497476f637a9 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -80,6 +80,13 @@ superio_inb(int reg) return inb(VAL); } +static inline void +superio_outb(int reg, int val) +{ + outb(reg, REG); + outb(val, VAL); +} + static int superio_inw(int reg) { int val; @@ -1036,6 +1043,21 @@ static int __init it87_find(unsigned short *address, sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); reg = superio_inb(IT87_SIO_PINX2_REG); + /* + * The IT8720F has no VIN7 pin, so VCCH should always be + * routed internally to VIN7 with an internal divider. + * Curiously, there still is a configuration bit to control + * this, which means it can be set incorrectly. And even + * more curiously, many boards out there are improperly + * configured, even though the IT8720F datasheet claims + * that the internal routing of VCCH to VIN7 is the default + * setting. So we force the internal routing in this case. + */ + if (sio_data->type == it8720 && !(reg & (1 << 1))) { + reg |= (1 << 1); + superio_outb(IT87_SIO_PINX2_REG, reg); + pr_notice("it87: Routing internal VCCH to in7\n"); + } if (reg & (1 << 0)) pr_info("it87: in3 is VCC (+5V)\n"); if (reg & (1 << 1)) diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 1fe995111841..4f84d1a76d52 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -120,7 +120,7 @@ static ssize_t show_temp(struct device *dev, int temp; struct k8temp_data *data = k8temp_update_device(dev); - if (data->swap_core_select) + if (data->swap_core_select && (data->sensorsp & SEL_CORE)) core = core ? 0 : 1; temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; @@ -143,6 +143,37 @@ static struct pci_device_id k8temp_ids[] = { MODULE_DEVICE_TABLE(pci, k8temp_ids); +static int __devinit is_rev_g_desktop(u8 model) +{ + u32 brandidx; + + if (model < 0x69) + return 0; + + if (model == 0xc1 || model == 0x6c || model == 0x7c) + return 0; + + /* + * Differentiate between AM2 and ASB1. + * See "Constructing the processor Name String" in "Revision + * Guide for AMD NPT Family 0Fh Processors" (33610). + */ + brandidx = cpuid_ebx(0x80000001); + brandidx = (brandidx >> 9) & 0x1f; + + /* Single core */ + if ((model == 0x6f || model == 0x7f) && + (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc)) + return 0; + + /* Dual core */ + if (model == 0x6b && + (brandidx == 0xb || brandidx == 0xc)) + return 0; + + return 1; +} + static int __devinit k8temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -179,12 +210,12 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, "wrong - check erratum #141\n"); } - if ((model >= 0x69) && - !(model == 0xc1 || model == 0x6c || model == 0x7c)) { + if (is_rev_g_desktop(model)) { /* - * RevG desktop CPUs (i.e. no socket S1G1 parts) - * need additional offset, otherwise reported - * temperature is below ambient temperature + * RevG desktop CPUs (i.e. no socket S1G1 or + * ASB1 parts) need additional offset, + * otherwise reported temperature is below + * ambient temperature */ data->temp_offset = 21000; } diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index cf5afb9a10ab..5d5ed69851db 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -127,12 +127,14 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) /* * Common configuration - * BDU: LSB and MSB values are not updated until both have been read. - * So the value read will always be correct. + * BDU: (12 bits sensors only) LSB and MSB values are not updated until + * both have been read. So the value read will always be correct. */ - lis3->read(lis3, CTRL_REG2, ®); - reg |= CTRL2_BDU; - lis3->write(lis3, CTRL_REG2, reg); + if (lis3->whoami == LIS_DOUBLE_ID) { + lis3->read(lis3, CTRL_REG2, ®); + reg |= CTRL2_BDU; + lis3->write(lis3, CTRL_REG2, reg); + } } EXPORT_SYMBOL_GPL(lis3lv02d_poweron); @@ -361,7 +363,8 @@ static ssize_t lis3lv02d_calibrate_store(struct device *dev, } /* conversion btw sampling rate and the register values */ -static int lis3lv02dl_df_val[4] = {40, 160, 640, 2560}; +static int lis3_12_rates[4] = {40, 160, 640, 2560}; +static int lis3_8_rates[2] = {100, 400}; static ssize_t lis3lv02d_rate_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -369,8 +372,13 @@ static ssize_t lis3lv02d_rate_show(struct device *dev, int val; lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); - val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; - return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); + + if (lis3_dev.whoami == LIS_DOUBLE_ID) + val = lis3_12_rates[(ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4]; + else + val = lis3_8_rates[(ctrl & CTRL1_DR) >> 7]; + + return sprintf(buf, "%d\n", val); } static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL); diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 3e1ff46f72d3..7cdd76f31ce3 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -103,6 +103,7 @@ enum lis3lv02d_ctrl1 { CTRL1_DF1 = 0x20, CTRL1_PD0 = 0x40, CTRL1_PD1 = 0x80, + CTRL1_DR = 0x80, /* Data rate on 8 bits */ }; enum lis3lv02d_ctrl2 { CTRL2_DAS = 0x01, diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 6c53d987de10..b0d03640af4b 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -1286,6 +1286,7 @@ static int lm85_probe(struct i2c_client *client, switch (data->type) { case adm1027: case adt7463: + case adt7468: case emc6d100: case emc6d102: data->freq_map = adm1027_freq_map; diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index 65c232a9d0c5..21d201befc2c 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c @@ -45,9 +45,7 @@ enum ltc4245_cmd { LTC4245_VEEIN = 0x19, LTC4245_VEESENSE = 0x1a, LTC4245_VEEOUT = 0x1b, - LTC4245_GPIOADC1 = 0x1c, - LTC4245_GPIOADC2 = 0x1d, - LTC4245_GPIOADC3 = 0x1e, + LTC4245_GPIOADC = 0x1c, }; struct ltc4245_data { @@ -61,7 +59,7 @@ struct ltc4245_data { u8 cregs[0x08]; /* Voltage registers */ - u8 vregs[0x0f]; + u8 vregs[0x0d]; }; static struct ltc4245_data *ltc4245_update_device(struct device *dev) @@ -86,7 +84,7 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev) data->cregs[i] = val; } - /* Read voltage registers -- 0x10 to 0x1f */ + /* Read voltage registers -- 0x10 to 0x1c */ for (i = 0; i < ARRAY_SIZE(data->vregs); i++) { val = i2c_smbus_read_byte_data(client, i+0x10); if (unlikely(val < 0)) @@ -128,9 +126,7 @@ static int ltc4245_get_voltage(struct device *dev, u8 reg) case LTC4245_VEEOUT: voltage = regval * -55; break; - case LTC4245_GPIOADC1: - case LTC4245_GPIOADC2: - case LTC4245_GPIOADC3: + case LTC4245_GPIOADC: voltage = regval * 10; break; default: @@ -297,9 +293,7 @@ LTC4245_ALARM(in7_min_alarm, (1 << 2), LTC4245_FAULT2); LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2); /* GPIO voltages */ -LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC1); -LTC4245_VOLTAGE(in10_input, LTC4245_GPIOADC2); -LTC4245_VOLTAGE(in11_input, LTC4245_GPIOADC3); +LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC); /* Power Consumption (virtual) */ LTC4245_POWER(power1_input, LTC4245_12VSENSE); @@ -342,8 +336,6 @@ static struct attribute *ltc4245_attributes[] = { &sensor_dev_attr_in8_min_alarm.dev_attr.attr, &sensor_dev_attr_in9_input.dev_attr.attr, - &sensor_dev_attr_in10_input.dev_attr.attr, - &sensor_dev_attr_in11_input.dev_attr.attr, &sensor_dev_attr_power1_input.dev_attr.attr, &sensor_dev_attr_power2_input.dev_attr.attr, diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 4a64b85d4ec9..68e69a49633c 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -1610,11 +1610,8 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) static int __init pc87360_device_add(unsigned short address) { - struct resource res = { - .name = "pc87360", - .flags = IORESOURCE_IO, - }; - int err, i; + struct resource res[3]; + int err, i, res_count; pdev = platform_device_alloc("pc87360", address); if (!pdev) { @@ -1623,22 +1620,28 @@ static int __init pc87360_device_add(unsigned short address) goto exit; } + memset(res, 0, 3 * sizeof(struct resource)); + res_count = 0; for (i = 0; i < 3; i++) { if (!extra_isa[i]) continue; - res.start = extra_isa[i]; - res.end = extra_isa[i] + PC87360_EXTENT - 1; + res[res_count].start = extra_isa[i]; + res[res_count].end = extra_isa[i] + PC87360_EXTENT - 1; + res[res_count].name = "pc87360", + res[res_count].flags = IORESOURCE_IO, - err = acpi_check_resource_conflict(&res); + err = acpi_check_resource_conflict(&res[res_count]); if (err) goto exit_device_put; - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR "pc87360: Device resource[%d] " - "addition failed (%d)\n", i, err); - goto exit_device_put; - } + res_count++; + } + + err = platform_device_add_resources(pdev, res, res_count); + if (err) { + printk(KERN_ERR "pc87360: Device resources addition failed " + "(%d)\n", err); + goto exit_device_put; } err = platform_device_add(pdev); diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 864a371f6eb9..fbc997ee67d9 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -302,13 +302,13 @@ static int sht15_update_vals(struct sht15_data *data) **/ static inline int sht15_calc_temp(struct sht15_data *data) { - int d1 = 0; + int d1 = temppoints[0].d1; int i; - for (i = 1; i < ARRAY_SIZE(temppoints); i++) + for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--) /* Find pointer to interpolate */ if (data->supply_uV > temppoints[i - 1].vdd) { - d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd) + d1 = (data->supply_uV - temppoints[i - 1].vdd) * (temppoints[i].d1 - temppoints[i - 1].d1) / (temppoints[i].vdd - temppoints[i - 1].vdd) + temppoints[i - 1].d1; @@ -541,7 +541,12 @@ static int __devinit sht15_probe(struct platform_device *pdev) /* If a regulator is available, query what the supply voltage actually is!*/ data->reg = regulator_get(data->dev, "vcc"); if (!IS_ERR(data->reg)) { - data->supply_uV = regulator_get_voltage(data->reg); + int voltage; + + voltage = regulator_get_voltage(data->reg); + if (voltage) + data->supply_uV = voltage; + regulator_enable(data->reg); /* setup a notifier block to update this if another device * causes the voltage to change */ diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 20924343431b..d3a786b36d6a 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -62,9 +62,9 @@ static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 }; #define TMP423_DEVICE_ID 0x23 static const struct i2c_device_id tmp421_id[] = { - { "tmp421", tmp421 }, - { "tmp422", tmp422 }, - { "tmp423", tmp423 }, + { "tmp421", 2 }, + { "tmp422", 3 }, + { "tmp423", 4 }, { } }; MODULE_DEVICE_TABLE(i2c, tmp421_id); @@ -74,21 +74,23 @@ struct tmp421_data { struct mutex update_lock; char valid; unsigned long last_updated; - int kind; + int channels; u8 config; s16 temp[4]; }; static int temp_from_s16(s16 reg) { - int temp = reg; + /* Mask out status bits */ + int temp = reg & ~0xf; return (temp * 1000 + 128) / 256; } static int temp_from_u16(u16 reg) { - int temp = reg; + /* Mask out status bits */ + int temp = reg & ~0xf; /* Add offset for extended temperature range. */ temp -= 64 * 256; @@ -108,7 +110,7 @@ static struct tmp421_data *tmp421_update_device(struct device *dev) data->config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1); - for (i = 0; i <= data->kind; i++) { + for (i = 0; i < data->channels; i++) { data->temp[i] = i2c_smbus_read_byte_data(client, TMP421_TEMP_MSB[i]) << 8; data->temp[i] |= i2c_smbus_read_byte_data(client, @@ -167,7 +169,7 @@ static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, devattr = container_of(a, struct device_attribute, attr); index = to_sensor_dev_attr(devattr)->index; - if (data->kind > index) + if (index < data->channels) return a->mode; return 0; @@ -275,7 +277,7 @@ static int tmp421_probe(struct i2c_client *client, i2c_set_clientdata(client, data); mutex_init(&data->update_lock); - data->kind = id->driver_data; + data->channels = id->driver_data; err = tmp421_init_client(client); if (err) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 51c404943ac8..eb6df5f1a6de 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -4,6 +4,270 @@ menu "I2C Hardware Bus support" +comment "PC SMBus host controller drivers" + depends on PCI + +config I2C_ALI1535 + tristate "ALI 1535" + depends on PCI + help + If you say yes to this option, support will be included for the SMB + Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB + controller is part of the 7101 device, which is an ACPI-compliant + Power Management Unit (PMU). + + This driver can also be built as a module. If so, the module + will be called i2c-ali1535. + +config I2C_ALI1563 + tristate "ALI 1563" + depends on PCI && EXPERIMENTAL + help + If you say yes to this option, support will be included for the SMB + Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB + controller is part of the 7101 device, which is an ACPI-compliant + Power Management Unit (PMU). + + This driver can also be built as a module. If so, the module + will be called i2c-ali1563. + +config I2C_ALI15X3 + tristate "ALI 15x3" + depends on PCI + help + If you say yes to this option, support will be included for the + Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces. + + This driver can also be built as a module. If so, the module + will be called i2c-ali15x3. + +config I2C_AMD756 + tristate "AMD 756/766/768/8111 and nVidia nForce" + depends on PCI + help + If you say yes to this option, support will be included for the AMD + 756/766/768 mainboard I2C interfaces. The driver also includes + support for the first (SMBus 1.0) I2C interface of the AMD 8111 and + the nVidia nForce I2C interface. + + This driver can also be built as a module. If so, the module + will be called i2c-amd756. + +config I2C_AMD756_S4882 + tristate "SMBus multiplexing on the Tyan S4882" + depends on I2C_AMD756 && X86 && EXPERIMENTAL + help + Enabling this option will add specific SMBus support for the Tyan + S4882 motherboard. On this 4-CPU board, the SMBus is multiplexed + over 8 different channels, where the various memory module EEPROMs + and temperature sensors live. Saying yes here will give you access + to these in addition to the trunk. + + This driver can also be built as a module. If so, the module + will be called i2c-amd756-s4882. + +config I2C_AMD8111 + tristate "AMD 8111" + depends on PCI + help + If you say yes to this option, support will be included for the + second (SMBus 2.0) AMD 8111 mainboard I2C interface. + + This driver can also be built as a module. If so, the module + will be called i2c-amd8111. + +config I2C_I801 + tristate "Intel 82801 (ICH/PCH)" + depends on PCI + help + If you say yes to this option, support will be included for the Intel + 801 family of mainboard I2C interfaces. Specifically, the following + versions of the chipset are supported: + 82801AA + 82801AB + 82801BA + 82801CA/CAM + 82801DB + 82801EB/ER (ICH5/ICH5R) + 6300ESB + ICH6 + ICH7 + ESB2 + ICH8 + ICH9 + Tolapai + ICH10 + 3400/5 Series (PCH) + Cougar Point (PCH) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. + +config I2C_ISCH + tristate "Intel SCH SMBus 1.0" + depends on PCI + help + Say Y here if you want to use SMBus controller on the Intel SCH + based systems. + + This driver can also be built as a module. If so, the module + will be called i2c-isch. + +config I2C_PIIX4 + tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)" + depends on PCI + help + If you say yes to this option, support will be included for the Intel + PIIX4 family of mainboard I2C interfaces. Specifically, the following + versions of the chipset are supported (note that Serverworks is part + of Broadcom): + Intel PIIX4 + Intel 440MX + ATI IXP200 + ATI IXP300 + ATI IXP400 + ATI SB600 + ATI SB700 + ATI SB800 + AMD Hudson-2 + Serverworks OSB4 + Serverworks CSB5 + Serverworks CSB6 + Serverworks HT-1000 + Serverworks HT-1100 + SMSC Victory66 + + This driver can also be built as a module. If so, the module + will be called i2c-piix4. + +config I2C_NFORCE2 + tristate "Nvidia nForce2, nForce3 and nForce4" + depends on PCI + help + If you say yes to this option, support will be included for the Nvidia + nForce2, nForce3 and nForce4 families of mainboard I2C interfaces. + + This driver can also be built as a module. If so, the module + will be called i2c-nforce2. + +config I2C_NFORCE2_S4985 + tristate "SMBus multiplexing on the Tyan S4985" + depends on I2C_NFORCE2 && X86 && EXPERIMENTAL + help + Enabling this option will add specific SMBus support for the Tyan + S4985 motherboard. On this 4-CPU board, the SMBus is multiplexed + over 4 different channels, where the various memory module EEPROMs + live. Saying yes here will give you access to these in addition + to the trunk. + + This driver can also be built as a module. If so, the module + will be called i2c-nforce2-s4985. + +config I2C_SIS5595 + tristate "SiS 5595" + depends on PCI + help + If you say yes to this option, support will be included for the + SiS5595 SMBus (a subset of I2C) interface. + + This driver can also be built as a module. If so, the module + will be called i2c-sis5595. + +config I2C_SIS630 + tristate "SiS 630/730" + depends on PCI + help + If you say yes to this option, support will be included for the + SiS630 and SiS730 SMBus (a subset of I2C) interface. + + This driver can also be built as a module. If so, the module + will be called i2c-sis630. + +config I2C_SIS96X + tristate "SiS 96x" + depends on PCI + help + If you say yes to this option, support will be included for the SiS + 96x SMBus (a subset of I2C) interfaces. Specifically, the following + chipsets are supported: + 645/961 + 645DX/961 + 645DX/962 + 648/961 + 650/961 + 735 + 745 + + This driver can also be built as a module. If so, the module + will be called i2c-sis96x. + +config I2C_VIA + tristate "VIA VT82C586B" + depends on PCI && EXPERIMENTAL + select I2C_ALGOBIT + help + If you say yes to this option, support will be included for the VIA + 82C586B I2C interface + + This driver can also be built as a module. If so, the module + will be called i2c-via. + +config I2C_VIAPRO + tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx" + depends on PCI + help + If you say yes to this option, support will be included for the VIA + VT82C596 and later SMBus interface. Specifically, the following + chipsets are supported: + VT82C596A/B + VT82C686A/B + VT8231 + VT8233/A + VT8235 + VT8237R/A/S + VT8251 + CX700 + VX800/VX820 + VX855/VX875 + + This driver can also be built as a module. If so, the module + will be called i2c-viapro. + +if ACPI + +comment "ACPI drivers" + +config I2C_SCMI + tristate "SMBus Control Method Interface" + help + This driver supports the SMBus Control Method Interface. It needs the + BIOS to declare ACPI control methods as described in the SMBus Control + Method Interface specification. + + To compile this driver as a module, choose M here: + the module will be called i2c-scmi. + +endif # ACPI + +comment "Mac SMBus host controller drivers" + depends on PPC_CHRP || PPC_PMAC + +config I2C_HYDRA + tristate "CHRP Apple Hydra Mac I/O I2C interface" + depends on PCI && PPC_CHRP && EXPERIMENTAL + select I2C_ALGOBIT + help + This supports the use of the I2C interface in the Apple Hydra Mac + I/O chip on some CHRP machines (e.g. the LongTrail). Say Y if you + have such a machine. + + This support is also available as a module. If so, the module + will be called i2c-hydra. + +config I2C_POWERMAC + tristate "Powermac I2C interface" + depends on PPC_PMAC + config I2C_RK2818 tristate "RK2818 i2c interface (I2C)" depends on ARCH_RK2818 diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 55edcfe5b851..806f033695b5 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -41,7 +41,8 @@ Tolapai 0x5032 32 hard yes yes yes ICH10 0x3a30 32 hard yes yes yes ICH10 0x3a60 32 hard yes yes yes - PCH 0x3b30 32 hard yes yes yes + 3400/5 Series (PCH) 0x3b30 32 hard yes yes yes + Cougar Point (PCH) 0x1c22 32 hard yes yes yes Features supported by this driver: Software PEC no @@ -415,9 +416,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, data->block[0] = 32; /* max for SMBus block reads */ } + /* Experience has shown that the block buffer can only be used for + SMBus (not I2C) block transactions, even though the datasheet + doesn't mention this limitation. */ if ((i801_features & FEATURE_BLOCK_BUFFER) - && !(command == I2C_SMBUS_I2C_BLOCK_DATA - && read_write == I2C_SMBUS_READ) + && command != I2C_SMBUS_I2C_BLOCK_DATA && i801_set_block_buffer_mode() == 0) result = i801_block_transaction_by_block(data, read_write, hwpec); @@ -578,6 +581,7 @@ static struct pci_device_id i801_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CPT_SMBUS) }, { 0, } }; @@ -707,6 +711,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id case PCI_DEVICE_ID_INTEL_ICH10_4: case PCI_DEVICE_ID_INTEL_ICH10_5: case PCI_DEVICE_ID_INTEL_PCH_SMBUS: + case PCI_DEVICE_ID_INTEL_CPT_SMBUS: i801_features |= FEATURE_I2C_BLOCK_READ; /* fall through */ case PCI_DEVICE_ID_INTEL_82801DB_3: diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index f7346a9bd95f..62a5ce527aad 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -71,8 +71,8 @@ static int pca_isa_readbyte(void *pd, int reg) static int pca_isa_waitforcompletion(void *pd) { - long ret = ~0; unsigned long timeout; + long ret; if (irq > -1) { ret = wait_event_timeout(pca_wait, @@ -81,11 +81,15 @@ static int pca_isa_waitforcompletion(void *pd) } else { /* Do polling */ timeout = jiffies + pca_isa_ops.timeout; - while (((pca_isa_readbyte(pd, I2C_PCA_CON) - & I2C_PCA_CON_SI) == 0) - && (ret = time_before(jiffies, timeout))) + do { + ret = time_before(jiffies, timeout); + if (pca_isa_readbyte(pd, I2C_PCA_CON) + & I2C_PCA_CON_SI) + break; udelay(100); + } while (ret); } + return ret > 0; } diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 5b2213df5ed0..fd295dd94986 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -80,8 +80,8 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) static int i2c_pca_pf_waitforcompletion(void *pd) { struct i2c_pca_pf_data *i2c = pd; - long ret = ~0; unsigned long timeout; + long ret; if (i2c->irq) { ret = wait_event_timeout(i2c->wait, @@ -90,10 +90,13 @@ static int i2c_pca_pf_waitforcompletion(void *pd) } else { /* Do polling */ timeout = jiffies + i2c->adap.timeout; - while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) - & I2C_PCA_CON_SI) == 0) - && (ret = time_before(jiffies, timeout))) + do { + ret = time_before(jiffies, timeout); + if (i2c->algo_data.read_byte(i2c, I2C_PCA_CON) + & I2C_PCA_CON_SI) + break; udelay(100); + } while (ret); } return ret > 0; @@ -221,7 +224,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) if (irq) { ret = request_irq(irq, i2c_pca_pf_handler, - IRQF_TRIGGER_FALLING, i2c->adap.name, i2c); + IRQF_TRIGGER_FALLING, pdev->name, i2c); if (ret) goto e_reqirq; } diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a59cba96f494..398881e40f6a 100755 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1391,14 +1391,24 @@ static int i2c_detect_address(struct i2c_client *temp_client, int kind, /* Make sure there is something at this address, unless forced */ if (kind < 0) { - if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, - I2C_SMBUS_QUICK, NULL) < 0) - return 0; + if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) { + /* Special probe for FSC hwmon chips */ + union i2c_smbus_data dummy; - /* prevent 24RF08 corruption */ - if ((addr & ~0x0f) == 0x50) - i2c_smbus_xfer(adapter, addr, 0, 0, 0, - I2C_SMBUS_QUICK, NULL); + if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE_DATA, &dummy) < 0) + return 0; + } else { + if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0, + I2C_SMBUS_QUICK, NULL) < 0) + return 0; + + /* Prevent 24RF08 corruption */ + if ((addr & ~0x0f) == 0x50) + i2c_smbus_xfer(adapter, addr, 0, + I2C_SMBUS_WRITE, 0, + I2C_SMBUS_QUICK, NULL); + } } /* Finally call the custom detection function */ diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index 1a32d62ed86b..a9c331301237 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -632,12 +632,10 @@ static void cmd640_init_dev(ide_drive_t *drive) static int cmd640_test_irq(ide_hwif_t *hwif) { - struct pci_dev *dev = to_pci_dev(hwif->dev); int irq_reg = hwif->channel ? ARTTIM23 : CFR; - u8 irq_stat, irq_mask = hwif->channel ? ARTTIM23_IDE23INTR : + u8 irq_mask = hwif->channel ? ARTTIM23_IDE23INTR : CFR_IDE01INTR; - - pci_read_config_byte(dev, irq_reg, &irq_stat); + u8 irq_stat = get_cmd640_reg(irq_reg); return (irq_stat & irq_mask) ? 1 : 0; } diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 64207df8da82..2de76cc08f61 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -506,15 +506,22 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, return (flags & REQ_FAILED) ? -EIO : 0; } -static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) +/* + * returns true if rq has been completed + */ +static bool ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) { unsigned int nr_bytes = cmd->nbytes - cmd->nleft; if (cmd->tf_flags & IDE_TFLAG_WRITE) nr_bytes -= cmd->last_xfer_len; - if (nr_bytes > 0) + if (nr_bytes > 0) { ide_complete_rq(drive, 0, nr_bytes); + return true; + } + + return false; } static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) @@ -679,7 +686,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } if (uptodate == 0 && rq->bio) - ide_cd_error_cmd(drive, cmd); + if (ide_cd_error_cmd(drive, cmd)) + return ide_stopped; /* make sure it's fully ended */ if (blk_fs_request(rq) == 0) { diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index cc8633cbe133..67fb73559fd5 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -428,13 +428,11 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, { struct request *rq; int error; + int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE; - rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq = blk_get_request(drive->queue, rw, __GFP_WAIT); rq->cmd_type = REQ_TYPE_ATA_TASKFILE; - if (cmd->tf_flags & IDE_TFLAG_WRITE) - rq->cmd_flags |= REQ_RW; - /* * (ks) We transfer currently only whole sectors. * This is suffient for now. But, it would be great, diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 66b41351910a..675fc042bc60 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -486,7 +486,8 @@ static int send_connect(struct iwch_ep *ep) V_MSS_IDX(mtu_idx) | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); - opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor); + opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) | + V_CONG_CONTROL_FLAVOR(cong_flavor); skb->priority = CPL_PRIORITY_SETUP; set_arp_failure_handler(skb, act_open_req_arp_failure); @@ -1303,7 +1304,8 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb) V_MSS_IDX(mtu_idx) | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); - opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor); + opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) | + V_CONG_CONTROL_FLAVOR(cong_flavor); rpl = cplhdr(skb); rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 30bdf427ee6d..f8302c267743 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -752,6 +752,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ if (++priv->tx_outstanding == ipoib_sendq_size) { ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", tx->qp->qp_num); + if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) + ipoib_warn(priv, "request notify on send CQ failed\n"); netif_stop_queue(dev); } } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index df3eb8c9fd96..b4b22576f12a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1163,7 +1163,7 @@ static ssize_t create_child(struct device *dev, return ret ? ret : count; } -static DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child); +static DEVICE_ATTR(create_child, S_IWUSR, NULL, create_child); static ssize_t delete_child(struct device *dev, struct device_attribute *attr, @@ -1183,7 +1183,7 @@ static ssize_t delete_child(struct device *dev, return ret ? ret : count; } -static DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child); +static DEVICE_ATTR(delete_child, S_IWUSR, NULL, delete_child); int ipoib_add_pkey_attr(struct net_device *dev) { diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index b9453d068e9d..274c883ef3ea 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c @@ -209,6 +209,8 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, mem_copy->copy_buf = NULL; } +#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0) + /** * iser_sg_to_page_vec - Translates scatterlist entries to physical addresses * and returns the length of resulting physical address array (may be less than @@ -221,62 +223,52 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task, * where --few fragments of the same page-- are present in the SG as * consecutive elements. Also, it handles one entry SG. */ + static int iser_sg_to_page_vec(struct iser_data_buf *data, struct iser_page_vec *page_vec, struct ib_device *ibdev) { - struct scatterlist *sgl = (struct scatterlist *)data->buf; - struct scatterlist *sg; - u64 first_addr, last_addr, page; - int end_aligned; - unsigned int cur_page = 0; + struct scatterlist *sg, *sgl = (struct scatterlist *)data->buf; + u64 start_addr, end_addr, page, chunk_start = 0; unsigned long total_sz = 0; - int i; + unsigned int dma_len; + int i, new_chunk, cur_page, last_ent = data->dma_nents - 1; /* compute the offset of first element */ page_vec->offset = (u64) sgl[0].offset & ~MASK_4K; + new_chunk = 1; + cur_page = 0; for_each_sg(sgl, sg, data->dma_nents, i) { - unsigned int dma_len = ib_sg_dma_len(ibdev, sg); - + start_addr = ib_sg_dma_address(ibdev, sg); + if (new_chunk) + chunk_start = start_addr; + dma_len = ib_sg_dma_len(ibdev, sg); + end_addr = start_addr + dma_len; total_sz += dma_len; - first_addr = ib_sg_dma_address(ibdev, sg); - last_addr = first_addr + dma_len; - - end_aligned = !(last_addr & ~MASK_4K); - - /* continue to collect page fragments till aligned or SG ends */ - while (!end_aligned && (i + 1 < data->dma_nents)) { - sg = sg_next(sg); - i++; - dma_len = ib_sg_dma_len(ibdev, sg); - total_sz += dma_len; - last_addr = ib_sg_dma_address(ibdev, sg) + dma_len; - end_aligned = !(last_addr & ~MASK_4K); + /* collect page fragments until aligned or end of SG list */ + if (!IS_4K_ALIGNED(end_addr) && i < last_ent) { + new_chunk = 0; + continue; } + new_chunk = 1; - /* handle the 1st page in the 1st DMA element */ - if (cur_page == 0) { - page = first_addr & MASK_4K; - page_vec->pages[cur_page] = page; - cur_page++; + /* address of the first page in the contiguous chunk; + masking relevant for the very first SG entry, + which might be unaligned */ + page = chunk_start & MASK_4K; + do { + page_vec->pages[cur_page++] = page; page += SIZE_4K; - } else - page = first_addr; - - for (; page < last_addr; page += SIZE_4K) { - page_vec->pages[cur_page] = page; - cur_page++; - } - + } while (page < end_addr); } + page_vec->data_size = total_sz; iser_dbg("page_vec->data_size:%d cur_page %d\n", page_vec->data_size,cur_page); return cur_page; } -#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0) /** * iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned @@ -284,42 +276,40 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data, * the number of entries which are aligned correctly. Supports the case where * consecutive SG elements are actually fragments of the same physcial page. */ -static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data, - struct ib_device *ibdev) +static int iser_data_buf_aligned_len(struct iser_data_buf *data, + struct ib_device *ibdev) { - struct scatterlist *sgl, *sg; - u64 end_addr, next_addr; - int i, cnt; - unsigned int ret_len = 0; + struct scatterlist *sgl, *sg, *next_sg = NULL; + u64 start_addr, end_addr; + int i, ret_len, start_check = 0; + + if (data->dma_nents == 1) + return 1; sgl = (struct scatterlist *)data->buf; + start_addr = ib_sg_dma_address(ibdev, sgl); - cnt = 0; for_each_sg(sgl, sg, data->dma_nents, i) { - /* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX " - "offset: %ld sz: %ld\n", i, - (unsigned long)sg_phys(sg), - (unsigned long)sg->offset, - (unsigned long)sg->length); */ - end_addr = ib_sg_dma_address(ibdev, sg) + - ib_sg_dma_len(ibdev, sg); - /* iser_dbg("Checking sg iobuf end address " - "0x%08lX\n", end_addr); */ - if (i + 1 < data->dma_nents) { - next_addr = ib_sg_dma_address(ibdev, sg_next(sg)); - /* are i, i+1 fragments of the same page? */ - if (end_addr == next_addr) { - cnt++; - continue; - } else if (!IS_4K_ALIGNED(end_addr)) { - ret_len = cnt + 1; - break; - } - } - cnt++; + if (start_check && !IS_4K_ALIGNED(start_addr)) + break; + + next_sg = sg_next(sg); + if (!next_sg) + break; + + end_addr = start_addr + ib_sg_dma_len(ibdev, sg); + start_addr = ib_sg_dma_address(ibdev, next_sg); + + if (end_addr == start_addr) { + start_check = 0; + continue; + } else + start_check = 1; + + if (!IS_4K_ALIGNED(end_addr)) + break; } - if (i == data->dma_nents) - ret_len = cnt; /* loop ended */ + ret_len = (next_sg) ? i : i+1; iser_dbg("Found %d aligned entries out of %d in sg:0x%p\n", ret_len, data->dma_nents, data); return ret_len; diff --git a/drivers/input/input.c b/drivers/input/input.c index 2266ecbfbc01..c82ae82cc43f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -24,6 +24,7 @@ #include #include #include +#include "input-compat.h" MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input core"); @@ -758,6 +759,40 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han return error; } +#ifdef CONFIG_COMPAT + +static int input_bits_to_string(char *buf, int buf_size, + unsigned long bits, bool skip_empty) +{ + int len = 0; + + if (INPUT_COMPAT_TEST) { + u32 dword = bits >> 32; + if (dword || !skip_empty) + len += snprintf(buf, buf_size, "%x ", dword); + + dword = bits & 0xffffffffUL; + if (dword || !skip_empty || len) + len += snprintf(buf + len, max(buf_size - len, 0), + "%x", dword); + } else { + if (bits || !skip_empty) + len += snprintf(buf, buf_size, "%lx", bits); + } + + return len; +} + +#else /* !CONFIG_COMPAT */ + +static int input_bits_to_string(char *buf, int buf_size, + unsigned long bits, bool skip_empty) +{ + return bits || !skip_empty ? + snprintf(buf, buf_size, "%lx", bits) : 0; +} + +#endif #ifdef CONFIG_PROC_FS @@ -826,14 +861,25 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, unsigned long *bitmap, int max) { int i; - - for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) - if (bitmap[i]) - break; + bool skip_empty = true; + char buf[18]; seq_printf(seq, "B: %s=", name); - for (; i >= 0; i--) - seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); + + for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { + if (input_bits_to_string(buf, sizeof(buf), + bitmap[i], skip_empty)) { + skip_empty = false; + seq_printf(seq, "%s%s", buf, i > 0 ? " " : ""); + } + } + + /* + * If no output was produced print a single 0. + */ + if (skip_empty) + seq_puts(seq, "0"); + seq_putc(seq, '\n'); } @@ -1122,14 +1168,23 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, { int i; int len = 0; + bool skip_empty = true; - for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) - if (bitmap[i]) - break; + for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { + len += input_bits_to_string(buf + len, max(buf_size - len, 0), + bitmap[i], skip_empty); + if (len) { + skip_empty = false; + if (i > 0) + len += snprintf(buf + len, max(buf_size - len, 0), " "); + } + } - for (; i >= 0; i--) - len += snprintf(buf + len, max(buf_size - len, 0), - "%lx%s", bitmap[i], i > 0 ? " " : ""); + /* + * If no output was produced print a single 0. + */ + if (len == 0) + len = snprintf(buf, buf_size, "%d", 0); if (add_cr) len += snprintf(buf + len, max(buf_size - len, 0), "\n"); @@ -1144,7 +1199,8 @@ static ssize_t input_dev_show_cap_##bm(struct device *dev, \ { \ struct input_dev *input_dev = to_input_dev(dev); \ int len = input_print_bitmap(buf, PAGE_SIZE, \ - input_dev->bm##bit, ev##_MAX, 1); \ + input_dev->bm##bit, ev##_MAX, \ + true); \ return min_t(int, len, PAGE_SIZE); \ } \ static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) @@ -1208,7 +1264,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, len = input_print_bitmap(&env->buf[env->buflen - 1], sizeof(env->buf) - env->buflen, - bitmap, max, 0); + bitmap, max, false); if (len >= (sizeof(env->buf) - env->buflen)) return -ENOMEM; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b1bd6dd32286..93c60e0f2b8e 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -481,6 +481,9 @@ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev, memcpy(joydev->abspam, abspam, len); + for (i = 0; i < joydev->nabs; i++) + joydev->absmap[joydev->abspam[i]] = i; + out: kfree(abspam); return retval; diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 9a2977c21696..2cfbc1752605 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -50,8 +50,12 @@ */ #define TWL4030_MAX_ROWS 8 /* TWL4030 hard limit */ #define TWL4030_MAX_COLS 8 -#define TWL4030_ROW_SHIFT 3 -#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS * TWL4030_MAX_COLS) +/* + * Note that we add space for an extra column so that we can handle + * row lines connected to the gnd (see twl4030_col_xlate()). + */ +#define TWL4030_ROW_SHIFT 4 +#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS << TWL4030_ROW_SHIFT) struct twl4030_keypad { unsigned short keymap[TWL4030_KEYMAP_SIZE]; @@ -181,7 +185,7 @@ static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state) return ret; } -static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) +static bool twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) { int i; u16 check = 0; @@ -190,12 +194,12 @@ static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) u16 col = key_state[i]; if ((col & check) && hweight16(col) > 1) - return 1; + return true; check |= col; } - return 0; + return false; } static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) @@ -224,7 +228,8 @@ static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) if (!changed) continue; - for (col = 0; col < kp->n_cols; col++) { + /* Extra column handles "all gnd" rows */ + for (col = 0; col < kp->n_cols + 1; col++) { int code; if (!(changed & (1 << col))) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index fc8823bcf20c..0c99db075e8f 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -62,6 +62,8 @@ static const struct alps_model_info alps_model_data[] = { { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */ + { { 0x52, 0x01, 0x14 }, 0xff, 0xff, + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ }; /* diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 0876d82cecfc..9451e28701f8 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1349,6 +1349,7 @@ static int psmouse_reconnect(struct serio *serio) struct psmouse *psmouse = serio_get_drvdata(serio); struct psmouse *parent = NULL; struct serio_driver *drv = serio->drv; + unsigned char type; int rc = -1; if (!drv || !psmouse) { @@ -1368,10 +1369,15 @@ static int psmouse_reconnect(struct serio *serio) if (psmouse->reconnect) { if (psmouse->reconnect(psmouse)) goto out; - } else if (psmouse_probe(psmouse) < 0 || - psmouse->type != psmouse_extensions(psmouse, - psmouse_max_proto, false)) { - goto out; + } else { + psmouse_reset(psmouse); + + if (psmouse_probe(psmouse) < 0) + goto out; + + type = psmouse_extensions(psmouse, psmouse_max_proto, false); + if (psmouse->type != type) + goto out; } /* ok, the device type (and capabilities) match the old one, diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2a5982e532f8..21ef4b59a818 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -165,6 +165,13 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { DMI_MATCH(DMI_BOARD_VERSION, "1.02"), }, }, + { + /* Gigabyte Spring Peak - defines wrong chassis type */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), + }, + }, { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), @@ -321,6 +328,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), }, }, + { + /* Sony Vaio VPCZ122GX */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VPCZ122GX"), + }, + }, { /* Sony Vaio FS-115b */ .matches = { @@ -441,6 +455,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), }, }, + { + /* Medion Akoya E1222 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), + }, + }, { /* Mivvy M310 */ .matches = { diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 1df02d25aca5..16f5ab2ee034 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1412,8 +1412,8 @@ static int __init i8042_init(void) static void __exit i8042_exit(void) { - platform_driver_unregister(&i8042_driver); platform_device_unregister(i8042_platform_device); + platform_driver_unregister(&i8042_driver); i8042_platform_exit(); panic_blink = NULL; diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 9114ae1c7488..e6307ba452ea 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom.h * - * USB Wacom Graphire and Wacom Intuos tablet support + * USB Wacom tablet support * * Copyright (c) 2000-2004 Vojtech Pavlik * Copyright (c) 2000 Andreas Bach Aaen @@ -69,6 +69,7 @@ * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 * v1.51 (pc) - Added support for Intuos4 + * v1.52 (pc) - Query Wacom data upon system resume */ /* @@ -89,9 +90,9 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.51" +#define DRIVER_VERSION "v1.52" #define DRIVER_AUTHOR "Vojtech Pavlik " -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" +#define DRIVER_DESC "USB Wacom tablet driver" #define DRIVER_LICENSE "GPL" MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index ea30c983a33e..69fc4b8d8738 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom_sys.c * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code + * USB Wacom tablet support - system specific code */ /* @@ -562,10 +562,15 @@ static int wacom_resume(struct usb_interface *intf) int rv; mutex_lock(&wacom->lock); + + /* switch to wacom mode first */ + wacom_query_tablet_data(intf); + if (wacom->open) rv = usb_submit_urb(wacom->irq, GFP_NOIO); else rv = 0; + mutex_unlock(&wacom->lock); return rv; diff --git a/drivers/input/touchscreen/hannstar_p1003.c b/drivers/input/touchscreen/hannstar_p1003.c index 726e10a84115..1b3f38cecff9 100755 --- a/drivers/input/touchscreen/hannstar_p1003.c +++ b/drivers/input/touchscreen/hannstar_p1003.c @@ -51,6 +51,7 @@ struct ts_p1003 { struct input_dev *input; char phys[32]; struct delayed_work work; + struct workqueue_struct *wq; struct i2c_client *client; struct multitouch_event mt_event; @@ -96,6 +97,8 @@ static void p1003_report_event(struct ts_p1003 *ts,struct multitouch_event *tc) ts->pendown = pandown; input_sync(input); } + +#if defined (Singltouch_Mode) static void p1003_report_single_event(struct ts_p1003 *ts,struct multitouch_event *tc) { struct input_dev *input = ts->input; @@ -114,6 +117,8 @@ static void p1003_report_single_event(struct ts_p1003 *ts,struct multitouch_even sakura_dbg_report_key_msg("%s x =0x%x,y = 0x%x \n",ts->status?"down":"up",tc->point_data[cid].x,tc->point_data[cid].y); } } +#endif + static inline int p1003_read_values(struct ts_p1003 *ts, struct multitouch_event *tc) { int data; @@ -164,13 +169,9 @@ static void p1003_work(struct work_struct *work) out: if (ts->pendown) - schedule_delayed_work(&ts->work, - msecs_to_jiffies(10)); + queue_delayed_work(ts->wq, &ts->work, msecs_to_jiffies(10)); else enable_irq(ts->irq); - - - return; } static irqreturn_t p1003_irq(int irq, void *handle) @@ -179,8 +180,7 @@ static irqreturn_t p1003_irq(int irq, void *handle) #if 1 if (!ts->get_pendown_state || likely(ts->get_pendown_state())) { disable_irq_nosync(ts->irq); - schedule_delayed_work(&ts->work, - msecs_to_jiffies(10)); + queue_delayed_work(ts->wq, &ts->work, 0); } #endif @@ -228,7 +228,8 @@ static int __devinit p1003_probe(struct i2c_client *client, ts->input = input_dev; ts->status =0 ;// fjp add by 2010-9-30 ts->pendown = 0; // fjp add by 2010-10-06 - + + ts->wq = create_rt_workqueue("p1003_wq"); INIT_DELAYED_WORK(&ts->work, p1003_work); ts->model = pdata->model; diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index cc768caa38f5..a0f7b99aee8b 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c @@ -1243,14 +1243,10 @@ static void do_action(int action, struct cardstate *cs, * note that bcs may be NULL if no B channel is free */ at_state2->ConState = 700; - kfree(at_state2->str_var[STR_NMBR]); - at_state2->str_var[STR_NMBR] = NULL; - kfree(at_state2->str_var[STR_ZCPN]); - at_state2->str_var[STR_ZCPN] = NULL; - kfree(at_state2->str_var[STR_ZBC]); - at_state2->str_var[STR_ZBC] = NULL; - kfree(at_state2->str_var[STR_ZHLC]); - at_state2->str_var[STR_ZHLC] = NULL; + for (i = 0; i < STR_NUM; ++i) { + kfree(at_state2->str_var[i]); + at_state2->str_var[i] = NULL; + } at_state2->int_var[VAR_ZCTP] = -1; spin_lock_irqsave(&cs->lock, flags); diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 6a8e1384e7bd..b3065b8b2456 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -635,7 +635,6 @@ void gigaset_if_receive(struct cardstate *cs, if ((tty = cs->tty) == NULL) gig_dbg(DEBUG_ANY, "receive on closed device"); else { - tty_buffer_request_room(tty, len); tty_insert_flip_string(tty, buffer, len); tty_flip_buffer_push(tty); } diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 1081091bbfaf..2655e3aab895 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c @@ -174,7 +174,7 @@ int sc_ioctl(int card, scs_ioctl *data) pr_debug("%s: SCIOGETSPID: ioctl received\n", sc_adapter[card]->devicename); - spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); + spid = kzalloc(SCIOC_SPIDSIZE, GFP_KERNEL); if (!spid) { kfree(rcvmsg); return -ENOMEM; @@ -194,7 +194,7 @@ int sc_ioctl(int card, scs_ioctl *data) kfree(rcvmsg); return status; } - strcpy(spid, rcvmsg->msg_data.byte_array); + strlcpy(spid, rcvmsg->msg_data.byte_array, SCIOC_SPIDSIZE); /* * Package the switch type and send to user space @@ -272,12 +272,12 @@ int sc_ioctl(int card, scs_ioctl *data) return status; } - dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL); + dn = kzalloc(SCIOC_DNSIZE, GFP_KERNEL); if (!dn) { kfree(rcvmsg); return -ENOMEM; } - strcpy(dn, rcvmsg->msg_data.byte_array); + strlcpy(dn, rcvmsg->msg_data.byte_array, SCIOC_DNSIZE); kfree(rcvmsg); /* @@ -348,7 +348,7 @@ int sc_ioctl(int card, scs_ioctl *data) pr_debug("%s: SCIOSTAT: ioctl received\n", sc_adapter[card]->devicename); - bi = kmalloc (sizeof(boardInfo), GFP_KERNEL); + bi = kzalloc(sizeof(boardInfo), GFP_KERNEL); if (!bi) { kfree(rcvmsg); return -ENOMEM; diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index e5225d28f392..0823e2622e8c 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -211,7 +211,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device_node *np = ofdev->node, *child; - struct gpio_led led; struct gpio_led_of_platform_data *pdata; int count = 0, ret; @@ -226,8 +225,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, if (!pdata) return -ENOMEM; - memset(&led, 0, sizeof(led)); for_each_child_of_node(np, child) { + struct gpio_led led = {}; enum of_gpio_flags flags; const char *state; diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 386a7972111d..a564fe2eff14 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -90,6 +90,8 @@ static struct task_struct *thread_therm = NULL; static void write_both_fan_speed(struct thermostat *th, int speed); static void write_fan_speed(struct thermostat *th, int speed, int fan); +static void thermostat_create_files(void); +static void thermostat_remove_files(void); static int write_reg(struct thermostat* th, int reg, u8 data) @@ -161,6 +163,8 @@ remove_thermostat(struct i2c_client *client) struct thermostat *th = i2c_get_clientdata(client); int i; + thermostat_remove_files(); + if (thread_therm != NULL) { kthread_stop(thread_therm); } @@ -449,6 +453,8 @@ static int probe_thermostat(struct i2c_client *client, return -ENOMEM; } + thermostat_create_files(); + return 0; } @@ -566,7 +572,6 @@ thermostat_init(void) struct device_node* np; const u32 *prop; int i = 0, offset = 0; - int err; np = of_find_node_by_name(NULL, "fan"); if (!np) @@ -633,6 +638,17 @@ thermostat_init(void) return -ENODEV; } +#ifndef CONFIG_I2C_POWERMAC + request_module("i2c-powermac"); +#endif + + return i2c_add_driver(&thermostat_driver); +} + +static void thermostat_create_files(void) +{ + int err; + err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); @@ -647,16 +663,9 @@ thermostat_init(void) if (err) printk(KERN_WARNING "Failed to create tempertaure attribute file(s).\n"); - -#ifndef CONFIG_I2C_POWERMAC - request_module("i2c-powermac"); -#endif - - return i2c_add_driver(&thermostat_driver); } -static void __exit -thermostat_exit(void) +static void thermostat_remove_files(void) { if (of_dev) { device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature); @@ -673,9 +682,14 @@ thermostat_exit(void) device_remove_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); - of_device_unregister(of_dev); } +} + +static void __exit +thermostat_exit(void) +{ i2c_del_driver(&thermostat_driver); + of_device_unregister(of_dev); } module_init(thermostat_init); diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index a5e5f2fbf963..47831536deb1 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1317,7 +1317,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto { if (!bitmap) return; if (behind) { - atomic_dec(&bitmap->behind_writes); + if (atomic_dec_and_test(&bitmap->behind_writes)) + wake_up(&bitmap->behind_wait); PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n", atomic_read(&bitmap->behind_writes), bitmap->max_write_behind); } @@ -1629,6 +1630,7 @@ int bitmap_create(mddev_t *mddev) atomic_set(&bitmap->pending_writes, 0); init_waitqueue_head(&bitmap->write_wait); init_waitqueue_head(&bitmap->overflow_wait); + init_waitqueue_head(&bitmap->behind_wait); bitmap->mddev = mddev; diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index 7e38d13ddcac..86950bc527af 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h @@ -254,6 +254,9 @@ struct bitmap { wait_queue_head_t write_wait; wait_queue_head_t overflow_wait; +#ifndef __GENKSYMS__ + wait_queue_head_t behind_wait; +#endif }; /* the bitmap API */ diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index 8a223a48802c..5f9315b32a42 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -162,7 +162,7 @@ static inline sector_t get_dev_size(struct block_device *bdev) static inline chunk_t sector_to_chunk(struct dm_exception_store *store, sector_t sector) { - return (sector & ~store->chunk_mask) >> store->chunk_shift; + return sector >> store->chunk_shift; } int dm_exception_store_type_register(struct dm_exception_store_type *type); diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index d19854c98184..818b617ab3b2 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -249,40 +249,46 @@ static void __hash_remove(struct hash_cell *hc) static void dm_hash_remove_all(int keep_open_devices) { - int i, dev_skipped, dev_removed; + int i, dev_skipped; struct hash_cell *hc; - struct list_head *tmp, *n; + struct mapped_device *md; + +retry: + dev_skipped = 0; down_write(&_hash_lock); -retry: - dev_skipped = dev_removed = 0; for (i = 0; i < NUM_BUCKETS; i++) { - list_for_each_safe (tmp, n, _name_buckets + i) { - hc = list_entry(tmp, struct hash_cell, name_list); + list_for_each_entry(hc, _name_buckets + i, name_list) { + md = hc->md; + dm_get(md); - if (keep_open_devices && - dm_lock_for_deletion(hc->md)) { + if (keep_open_devices && dm_lock_for_deletion(md)) { + dm_put(md); dev_skipped++; continue; } + __hash_remove(hc); - dev_removed = 1; + + up_write(&_hash_lock); + + dm_put(md); + + /* + * Some mapped devices may be using other mapped + * devices, so repeat until we make no further + * progress. If a new mapped device is created + * here it will also get removed. + */ + goto retry; } } - /* - * Some mapped devices may be using other mapped devices, so if any - * still exist, repeat until we make no further progress. - */ - if (dev_skipped) { - if (dev_removed) - goto retry; - - DMWARN("remove_all left %d open device(s)", dev_skipped); - } - up_write(&_hash_lock); + + if (dev_skipped) + DMWARN("remove_all left %d open device(s)", dev_skipped); } static int dm_hash_rename(uint32_t cookie, const char *old, const char *new) diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 32d0b878eccc..f336c6959082 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -691,6 +691,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as, if (as->argc < nr_params) { ti->error = "not enough path parameters"; + r = -EINVAL; goto bad; } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 724efc63904d..d7786e3514cd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -614,8 +614,10 @@ static void dec_pending(struct dm_io *io, int error) if (!md->barrier_error && io_error != -EOPNOTSUPP) md->barrier_error = io_error; end_io_acct(io); + free_io(md, io); } else { end_io_acct(io); + free_io(md, io); if (io_error != DM_ENDIO_REQUEUE) { trace_block_bio_complete(md->queue, bio); @@ -623,8 +625,6 @@ static void dec_pending(struct dm_io *io, int error) bio_endio(bio, io_error); } } - - free_io(md, io); } } @@ -1487,10 +1487,15 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq) return BLKPREP_OK; } -static void map_request(struct dm_target *ti, struct request *rq, - struct mapped_device *md) +/* + * Returns: + * 0 : the request has been processed (not requeued) + * !0 : the request has been requeued + */ +static int map_request(struct dm_target *ti, struct request *rq, + struct mapped_device *md) { - int r; + int r, requeued = 0; struct request *clone = rq->special; struct dm_rq_target_io *tio = clone->end_io_data; @@ -1516,6 +1521,7 @@ static void map_request(struct dm_target *ti, struct request *rq, case DM_MAPIO_REQUEUE: /* The target wants to requeue the I/O */ dm_requeue_unmapped_request(clone); + requeued = 1; break; default: if (r > 0) { @@ -1527,6 +1533,8 @@ static void map_request(struct dm_target *ti, struct request *rq, dm_kill_unmapped_request(clone, r); break; } + + return requeued; } /* @@ -1568,12 +1576,17 @@ static void dm_request_fn(struct request_queue *q) blk_start_request(rq); spin_unlock(q->queue_lock); - map_request(ti, rq, md); + if (map_request(ti, rq, md)) + goto requeued; + spin_lock_irq(q->queue_lock); } goto out; +requeued: + spin_lock_irq(q->queue_lock); + plug_and_out: if (!elv_queue_empty(q)) /* Some requests still remain, retry later */ diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 1ceceb334d5e..dff9d2f449c3 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -172,12 +172,14 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit max_phys_segments to 1 lying within + * a single page. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_phys_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } conf->array_sectors += rdev->sectors; cnt++; diff --git a/drivers/md/md.c b/drivers/md/md.c index 08f7471d0150..035274682459 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1122,7 +1122,7 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); - return num_sectors / 2; /* kB for sysfs */ + return num_sectors; } @@ -1485,7 +1485,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); md_super_wait(rdev->mddev); - return num_sectors / 2; /* kB for sysfs */ + return num_sectors; } static struct super_type super_types[] = { @@ -2011,12 +2011,18 @@ static void md_update_sb(mddev_t * mddev, int force_change) if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */ /* .. if the array isn't clean, an 'even' event must also go * to spares. */ - if ((mddev->events&1)==0) + if ((mddev->events&1)==0) { nospares = 0; + sync_req = 2; /* force a second update to get the + * even/odd in sync */ + } } else { /* otherwise an 'odd' event must go to spares */ - if ((mddev->events&1)) + if ((mddev->events&1)) { nospares = 0; + sync_req = 2; /* force a second update to get the + * even/odd in sync */ + } } } @@ -5328,6 +5334,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, int err = 0; void __user *argp = (void __user *)arg; mddev_t *mddev = NULL; + int ro; if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -5463,6 +5470,34 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, err = do_md_stop(mddev, 1, 1); goto done_unlock; + case BLKROSET: + if (get_user(ro, (int __user *)(arg))) { + err = -EFAULT; + goto done_unlock; + } + err = -EINVAL; + + /* if the bdev is going readonly the value of mddev->ro + * does not matter, no writes are coming + */ + if (ro) + goto done_unlock; + + /* are we are already prepared for writes? */ + if (mddev->ro != 1) + goto done_unlock; + + /* transitioning to readauto need only happen for + * arrays that call md_write_start + */ + if (mddev->pers) { + err = restart_array(mddev); + if (err == 0) { + mddev->ro = 2; + set_disk_ro(mddev->gendisk, 0); + } + } + goto done_unlock; } /* diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index ee7646f974a0..e4b11f18adc7 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -301,14 +301,16 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) rdev->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit ->max_phys_segments to one, lying + * within a single page. * (Note: it is very unlikely that a device with * merge_bvec_fn will be involved in multipath.) */ - if (q->merge_bvec_fn && - queue_max_sectors(q) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + if (q->merge_bvec_fn) { + blk_queue_max_phys_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } conf->working_disks++; mddev->degraded--; @@ -476,9 +478,11 @@ static int multipath_run (mddev_t *mddev) /* as we don't honour merge_bvec_fn, we must never risk * violating it, not that we ever expect a device with * a merge_bvec_fn to be involved in multipath */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_phys_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } if (!test_bit(Faulty, &rdev->flags)) conf->working_disks++; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index d3a4ce06015a..3db857cdd33e 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -176,14 +176,15 @@ static int create_strip_zones(mddev_t *mddev) disk_stack_limits(mddev->gendisk, rdev1->bdev, rdev1->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit ->max_phys_segments to 1, lying within + * a single page. */ - if (rdev1->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); - + if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_phys_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } if (!smallest || (rdev1->sectors < smallest->sectors)) smallest = rdev1; cnt++; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index e07ce2e033a9..968cb14b63c0 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -417,7 +417,7 @@ static void raid1_end_write_request(struct bio *bio, int error) */ static int read_balance(conf_t *conf, r1bio_t *r1_bio) { - const unsigned long this_sector = r1_bio->sector; + const sector_t this_sector = r1_bio->sector; int new_disk = conf->last_used, disk = new_disk; int wonly_disk = -1; const int sectors = r1_bio->sectors; @@ -433,7 +433,7 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) retry: if (conf->mddev->recovery_cp < MaxSector && (this_sector + sectors >= conf->next_resync)) { - /* Choose the first operation device, for consistancy */ + /* Choose the first operational device, for consistancy */ new_disk = 0; for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); @@ -845,6 +845,15 @@ static int make_request(struct request_queue *q, struct bio * bio) } mirror = conf->mirrors + rdisk; + if (test_bit(WriteMostly, &mirror->rdev->flags) && + bitmap) { + /* Reading from a write-mostly device must + * take care not to over-take any writes + * that are 'behind' + */ + wait_event(bitmap->behind_wait, + atomic_read(&bitmap->behind_writes) == 0); + } r1_bio->read_disk = rdisk; read_bio = bio_clone(bio, GFP_NOIO); @@ -891,9 +900,10 @@ static int make_request(struct request_queue *q, struct bio * bio) if (test_bit(Faulty, &rdev->flags)) { rdev_dec_pending(rdev, mddev); r1_bio->bios[i] = NULL; - } else + } else { r1_bio->bios[i] = bio; - targets++; + targets++; + } } else r1_bio->bios[i] = NULL; } @@ -921,9 +931,13 @@ static int make_request(struct request_queue *q, struct bio * bio) set_bit(R1BIO_Degraded, &r1_bio->state); } - /* do behind I/O ? */ + /* do behind I/O ? + * Not if there are too many, or cannot allocate memory, + * or a reader on WriteMostly is waiting for behind writes + * to flush */ if (bitmap && atomic_read(&bitmap->behind_writes) < bitmap->max_write_behind && + !waitqueue_active(&bitmap->behind_wait) && (behind_pages = alloc_behind_pages(bio)) != NULL) set_bit(R1BIO_BehindIO, &r1_bio->state); @@ -1174,6 +1188,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) * is not possible. */ if (!test_bit(Faulty, &rdev->flags) && + !mddev->recovery_disabled && mddev->degraded < conf->raid_disks) { err = -EBUSY; goto abort; @@ -2104,15 +2119,13 @@ static int stop(mddev_t *mddev) { conf_t *conf = mddev->private; struct bitmap *bitmap = mddev->bitmap; - int behind_wait = 0; /* wait for behind writes to complete */ - while (bitmap && atomic_read(&bitmap->behind_writes) > 0) { - behind_wait++; - printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop (%d)\n", mdname(mddev), behind_wait); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); /* wait a second */ + if (bitmap && atomic_read(&bitmap->behind_writes) > 0) { + printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop.\n", mdname(mddev)); /* need to kick something here to make sure I/O goes? */ + wait_event(bitmap->behind_wait, + atomic_read(&bitmap->behind_writes) == 0); } raise_barrier(conf); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c2cb7b87b440..1b4e232bce3c 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -493,7 +493,7 @@ static int raid10_mergeable_bvec(struct request_queue *q, */ static int read_balance(conf_t *conf, r10bio_t *r10_bio) { - const unsigned long this_sector = r10_bio->sector; + const sector_t this_sector = r10_bio->sector; int disk, slot, nslot; const int sectors = r10_bio->sectors; sector_t new_distance, current_distance; @@ -824,11 +824,29 @@ static int make_request(struct request_queue *q, struct bio * bio) */ bp = bio_split(bio, chunk_sects - (bio->bi_sector & (chunk_sects - 1)) ); + + /* Each of these 'make_request' calls will call 'wait_barrier'. + * If the first succeeds but the second blocks due to the resync + * thread raising the barrier, we will deadlock because the + * IO to the underlying device will be queued in generic_make_request + * and will never complete, so will never reduce nr_pending. + * So increment nr_waiting here so no new raise_barriers will + * succeed, and so the second wait_barrier cannot block. + */ + spin_lock_irq(&conf->resync_lock); + conf->nr_waiting++; + spin_unlock_irq(&conf->resync_lock); + if (make_request(q, &bp->bio1)) generic_make_request(&bp->bio1); if (make_request(q, &bp->bio2)) generic_make_request(&bp->bio2); + spin_lock_irq(&conf->resync_lock); + conf->nr_waiting--; + wake_up(&conf->wait_barrier); + spin_unlock_irq(&conf->resync_lock); + bio_pair_release(bp); return 0; bad_map: @@ -1155,13 +1173,17 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); - /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + /* as we don't honour merge_bvec_fn, we must + * never risk violating it, so limit + * ->max_phys_segments to one lying with a single + * page, as a one page request is never in + * violation. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_phys_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } p->head_position = 0; rdev->raid_disk = mirror; @@ -2155,12 +2177,14 @@ static int run(mddev_t *mddev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit max_phys_segments to 1 lying + * within a single page. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_phys_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } disk->head_position = 0; } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 431b9b26ca5d..23949739fc25 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1526,7 +1526,7 @@ static void raid5_end_read_request(struct bio * bi, int error) clear_bit(R5_UPTODATE, &sh->dev[i].flags); atomic_inc(&rdev->read_errors); - if (conf->mddev->degraded) + if (conf->mddev->degraded >= conf->max_degraded) printk_rl(KERN_WARNING "raid5:%s: read error not correctable " "(sector %llu on %s).\n", @@ -1649,8 +1649,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, int previous, int *dd_idx, struct stripe_head *sh) { - long stripe; - unsigned long chunk_number; + sector_t stripe, stripe2; + sector_t chunk_number; unsigned int chunk_offset; int pd_idx, qd_idx; int ddf_layout = 0; @@ -1670,18 +1670,13 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, */ chunk_offset = sector_div(r_sector, sectors_per_chunk); chunk_number = r_sector; - BUG_ON(r_sector != chunk_number); /* * Compute the stripe number */ - stripe = chunk_number / data_disks; - - /* - * Compute the data disk and parity disk indexes inside the stripe - */ - *dd_idx = chunk_number % data_disks; - + stripe = chunk_number; + *dd_idx = sector_div(stripe, data_disks); + stripe2 = stripe; /* * Select the parity disk based on the user selected algorithm. */ @@ -1693,21 +1688,21 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, case 5: switch (algorithm) { case ALGORITHM_LEFT_ASYMMETRIC: - pd_idx = data_disks - stripe % raid_disks; + pd_idx = data_disks - sector_div(stripe2, raid_disks); if (*dd_idx >= pd_idx) (*dd_idx)++; break; case ALGORITHM_RIGHT_ASYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); if (*dd_idx >= pd_idx) (*dd_idx)++; break; case ALGORITHM_LEFT_SYMMETRIC: - pd_idx = data_disks - stripe % raid_disks; + pd_idx = data_disks - sector_div(stripe2, raid_disks); *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; break; case ALGORITHM_RIGHT_SYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; break; case ALGORITHM_PARITY_0: @@ -1727,7 +1722,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, switch (algorithm) { case ALGORITHM_LEFT_ASYMMETRIC: - pd_idx = raid_disks - 1 - (stripe % raid_disks); + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1736,7 +1731,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, (*dd_idx) += 2; /* D D P Q D */ break; case ALGORITHM_RIGHT_ASYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1745,12 +1740,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, (*dd_idx) += 2; /* D D P Q D */ break; case ALGORITHM_LEFT_SYMMETRIC: - pd_idx = raid_disks - 1 - (stripe % raid_disks); + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = (pd_idx + 1) % raid_disks; *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; break; case ALGORITHM_RIGHT_SYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); qd_idx = (pd_idx + 1) % raid_disks; *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; break; @@ -1769,7 +1764,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, /* Exactly the same as RIGHT_ASYMMETRIC, but or * of blocks for computing Q is different. */ - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1784,7 +1779,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, * D D D P Q rather than * Q D D D P */ - pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks); + stripe2 += 1; + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1796,7 +1792,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, case ALGORITHM_ROTATING_N_CONTINUE: /* Same as left_symmetric but Q is before P */ - pd_idx = raid_disks - 1 - (stripe % raid_disks); + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = (pd_idx + raid_disks - 1) % raid_disks; *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; ddf_layout = 1; @@ -1804,27 +1800,27 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, case ALGORITHM_LEFT_ASYMMETRIC_6: /* RAID5 left_asymmetric, with Q on last device */ - pd_idx = data_disks - stripe % (raid_disks-1); + pd_idx = data_disks - sector_div(stripe2, raid_disks-1); if (*dd_idx >= pd_idx) (*dd_idx)++; qd_idx = raid_disks - 1; break; case ALGORITHM_RIGHT_ASYMMETRIC_6: - pd_idx = stripe % (raid_disks-1); + pd_idx = sector_div(stripe2, raid_disks-1); if (*dd_idx >= pd_idx) (*dd_idx)++; qd_idx = raid_disks - 1; break; case ALGORITHM_LEFT_SYMMETRIC_6: - pd_idx = data_disks - stripe % (raid_disks-1); + pd_idx = data_disks - sector_div(stripe2, raid_disks-1); *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); qd_idx = raid_disks - 1; break; case ALGORITHM_RIGHT_SYMMETRIC_6: - pd_idx = stripe % (raid_disks-1); + pd_idx = sector_div(stripe2, raid_disks-1); *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); qd_idx = raid_disks - 1; break; @@ -1869,14 +1865,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) : conf->algorithm; sector_t stripe; int chunk_offset; - int chunk_number, dummy1, dd_idx = i; + sector_t chunk_number; + int dummy1, dd_idx = i; sector_t r_sector; struct stripe_head sh2; chunk_offset = sector_div(new_sector, sectors_per_chunk); stripe = new_sector; - BUG_ON(new_sector != stripe); if (i == sh->pd_idx) return 0; @@ -1969,7 +1965,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) } chunk_number = stripe * data_disks + i; - r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; + r_sector = chunk_number * sectors_per_chunk + chunk_offset; check = raid5_compute_sector(conf, r_sector, previous, &dummy1, &sh2); diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 0241a7c5c34a..55e591daf717 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -350,6 +350,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) const u8 *ts, *ts_end, *from_where = NULL; u8 ts_remain = 0, how_much = 0, new_ts = 1; struct ethhdr *ethh = NULL; + bool error = false; #ifdef ULE_DEBUG /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */ @@ -459,10 +460,16 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); + error = true; + dev_kfree_skb(priv->ule_skb); + } + + if (error || priv->ule_sndu_remain) { dev->stats.rx_errors++; dev->stats.rx_frame_errors++; + error = false; } + reset_ule(priv); priv->need_pusi = 1; continue; @@ -504,6 +511,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) "bytes left in TS. Resyncing.\n", ts_remain); priv->ule_sndu_len = 0; priv->need_pusi = 1; + ts += TS_SZ; continue; } @@ -533,6 +541,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) from_where += 2; } + priv->ule_sndu_remain = priv->ule_sndu_len + 2; /* * State of current TS: * ts_remain (remaining bytes in the current TS cell) @@ -542,6 +551,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) */ switch (ts_remain) { case 1: + priv->ule_sndu_remain--; priv->ule_sndu_type = from_where[0] << 8; priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ ts_remain -= 1; from_where += 1; @@ -555,6 +565,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) default: /* complete ULE header is present in current TS. */ /* Extract ULE type field. */ if (priv->ule_sndu_type_1) { + priv->ule_sndu_type_1 = 0; priv->ule_sndu_type |= from_where[0]; from_where += 1; /* points to payload start. */ ts_remain -= 1; diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 0e4b97fba384..690823fc1cae 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -112,8 +112,8 @@ config DVB_USB_CXUSB select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE select DVB_DIB7000P if !DVB_FE_CUSTOMISE - select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE + select DVB_LGS8GXX if !DVB_FE_CUSTOMISE select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c index 3051b64aa17c..445fa1068064 100644 --- a/drivers/media/dvb/frontends/l64781.c +++ b/drivers/media/dvb/frontends/l64781.c @@ -192,8 +192,8 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa spi_bias *= qam_tab[p->constellation]; spi_bias /= p->code_rate_HP + 1; spi_bias /= (guard_tab[p->guard_interval] + 32); - spi_bias *= 1000ULL; - spi_bias /= 1000ULL + ppm/1000; + spi_bias *= 1000; + spi_bias /= 1000 + ppm/1000; spi_bias *= p->code_rate_HP; val0x04 = (p->transmission_mode << 2) | p->guard_interval; diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index d8d4214fd65f..32a7ec65ec42 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -68,13 +68,14 @@ config DVB_BUDGET select DVB_VES1820 if !DVB_FE_CUSTOMISE select DVB_L64781 if !DVB_FE_CUSTOMISE select DVB_TDA8083 if !DVB_FE_CUSTOMISE - select DVB_TDA10021 if !DVB_FE_CUSTOMISE - select DVB_TDA10023 if !DVB_FE_CUSTOMISE select DVB_S5H1420 if !DVB_FE_CUSTOMISE select DVB_TDA10086 if !DVB_FE_CUSTOMISE select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE + select DVB_ISL6423 if !DVB_FE_CUSTOMISE + select DVB_STV090x if !DVB_FE_CUSTOMISE + select DVB_STV6110x if !DVB_FE_CUSTOMISE help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard MPEG2 decoder, and without diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index e48380c48990..95a463c1ef85 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -643,9 +643,6 @@ static void frontend_init(struct budget *budget) &budget->i2c_adap, &tt1600_isl6423_config); - } else { - dvb_frontend_detach(budget->dvb_frontend); - budget->dvb_frontend = NULL; } } break; diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index e0dafb85d854..394cb0b745fc 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -975,6 +975,19 @@ config VIDEO_RK29_WORK_ONEFRAME config VIDEO_RK29_WORK_PINGPONG bool "VIP PingPong Mode" endchoice +choice + prompt "RK29XX camera sensor interface work with IPP " + depends on VIDEO_RK29 && RK29_IPP + default VIDEO_RK29_WORK_IPP + ---help--- + RK29 Camera Sensor Interface(VIP) can work with IPP or not IPP +config VIDEO_RK29_WORK_IPP + bool "VIP work with IPP" + +config VIDEO_RK29_WORK_NOT_IPP + bool "VIP don't work with IPP" +endchoice + # # USB Multimedia device configuration # diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a6724019c66f..d258ed719b7d 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -4468,6 +4468,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, request_modules(btv); } + init_bttv_i2c_ir(btv); bttv_input_init(btv); /* everything is fine */ diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index beda363418b0..3eb7c2952c8b 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c @@ -388,7 +388,12 @@ int __devinit init_bttv_i2c(struct bttv *btv) if (0 == btv->i2c_rc && i2c_scan) do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); - /* Instantiate the IR receiver device, if present */ + return btv->i2c_rc; +} + +/* Instantiate the I2C IR receiver device, if present */ +void __devinit init_bttv_i2c_ir(struct bttv *btv) +{ if (0 == btv->i2c_rc) { struct i2c_board_info info; /* The external IR receiver is at i2c address 0x34 (0x35 for @@ -408,7 +413,6 @@ int __devinit init_bttv_i2c(struct bttv *btv) strlcpy(info.type, "ir_video", I2C_NAME_SIZE); i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); } - return btv->i2c_rc; } int __devexit fini_bttv_i2c(struct bttv *btv) diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index a1d0e9c9f286..6cccc2a17eee 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h @@ -279,6 +279,7 @@ extern unsigned int bttv_debug; extern unsigned int bttv_gpio; extern void bttv_gpio_tracking(struct bttv *btv, char *comment); extern int init_bttv_i2c(struct bttv *btv); +extern void init_bttv_i2c_ir(struct bttv *btv); extern int fini_bttv_i2c(struct bttv *btv); #define bttv_printk if (bttv_verbose) printk diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 319c459459e0..dd30b9dad4a6 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -225,14 +225,16 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) dev->board.name, dev->model); /* set the direction for GPIO pins */ - cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); - cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); - cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); + if (dev->board.tuner_gpio) { + cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); + cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); + cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); - /* request some modules if any required */ + /* request some modules if any required */ - /* reset the Tuner */ - cx231xx_gpio_set(dev, dev->board.tuner_gpio); + /* reset the Tuner */ + cx231xx_gpio_set(dev, dev->board.tuner_gpio); + } /* set the mode to Analog mode initially */ cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 4172cb387420..d4746e064516 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - i2c_new_probed_device(&bus->i2c_adap, &info, addr_list); + /* + * We can't call i2c_new_probed_device() because it uses + * quick writes for probing and the IR receiver device only + * replies to reads. + */ + if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0, + I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK, + NULL) >= 0) { + info.addr = addr_list[0]; + i2c_new_device(&bus->i2c_adap, &info); + } } return bus->i2c_rc; diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index ee1ca39db06a..fb39f1184558 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c @@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) 0x18, 0x6b, 0x71, I2C_CLIENT_END }; + const unsigned short *addrp; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - i2c_new_probed_device(&core->i2c_adap, &info, addr_list); + /* + * We can't call i2c_new_probed_device() because it uses + * quick writes for probing and at least some R receiver + * devices only reply to reads. + */ + for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) { + if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0, + I2C_SMBUS_READ, 0, + I2C_SMBUS_QUICK, NULL) >= 0) { + info.addr = *addrp; + i2c_new_device(&core->i2c_adap, &info); + break; + } + } } return core->i2c_rc; } diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index db749461e5c6..efddf15d498c 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -610,6 +610,7 @@ static int dvb_fini(struct em28xx *dev) if (dev->dvb) { unregister_dvb(dev->dvb); + kfree(dev->dvb); dev->dvb = NULL; } diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index f8328b9efae5..d61767cd7a51 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -530,6 +530,12 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) {0x13, 0x00, {0x01}, 1}, {0, 0, {0}, 0} }; + /* Without this command the cam won't work with USB-UHCI */ + gspca_dev->usb_buf[0] = 0x0a; + gspca_dev->usb_buf[1] = 0x00; + err_code = mr_write(gspca_dev, 2); + if (err_code < 0) + return err_code; err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, ARRAY_SIZE(cif_sensor1_init_data)); } diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index bfae63f5584c..7878182a67b2 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -497,8 +497,6 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 }, /* QuickCam Messenger (new) */ {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Messenger (new) */ - {USB_DEVICE(0x046D, 0x08DA), .driver_info = BRIDGE_ST6422 }, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index fa6bb85cb4b0..6b61bb67e9d1 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -457,6 +457,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar struct fb_vblank vblank; u32 trace; + memset(&vblank, 0, sizeof(struct fb_vblank)); + vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC; trace = read_reg(0x028c0) >> 16; diff --git a/drivers/media/video/ov2659.c b/drivers/media/video/ov2659.c index e85a8bdbf954..59f3cafb4dd1 100644 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -1411,7 +1411,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) struct sensor *sensor = to_sensor(client); struct v4l2_pix_format *pix = &f->fmt.pix; struct reginfo *winseqe_set_addr=NULL; - int ret, set_w,set_h; + int ret=0, set_w,set_h; if (sensor->info_priv.pixfmt != pix->pixelformat) { switch (pix->pixelformat) @@ -1489,21 +1489,21 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - + ret = -1; SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - ret = sensor_write_array(client, winseqe_set_addr); - if (ret != 0) - { + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - return ret; + goto sensor_s_fmt_end; } sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); } else @@ -1511,7 +1511,11 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_TR("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - return 0; + pix->width = set_w; + pix->height = set_h; + +sensor_s_fmt_end: + return ret; } static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c index 7a830987610c..d38d3af218e9 100644 --- a/drivers/media/video/ov5642.c +++ b/drivers/media/video/ov5642.c @@ -476,8 +476,8 @@ static struct reginfo sensor_init_data[] = {0x370b , 0x40}, {0x370d , 0x02}, {0x3620 , 0x52}, - - {0X0000, 0X00} + {0x3c00 , 0x04}, + {0X0000 , 0x00} }; /* 2592X1944 QSXGA */ @@ -1819,7 +1819,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) struct sensor *sensor = to_sensor(client); struct v4l2_pix_format *pix = &f->fmt.pix; struct reginfo *winseqe_set_addr=NULL; - int ret, set_w,set_h; + int ret = 0, set_w,set_h; if (sensor->info_priv.pixfmt != pix->pixelformat) { switch (pix->pixelformat) @@ -1904,31 +1904,29 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) set_w = 2592; set_h = 1944; } - else if (sensor_qvga[0].reg) + else { - winseqe_set_addr = sensor_qvga; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = 320; - set_h = 240; - } - else - { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + ret = -1; SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); - return -EINVAL; - } + } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - ret = sensor_write_array(client, winseqe_set_addr); - if (ret != 0) - { + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - return ret; + goto sensor_s_fmt_end; } sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; #if CONFIG_SENSOR_Focus sensor_af_zoneupdate(client); #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); } else @@ -1936,7 +1934,10 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_TR("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - return 0; + pix->width = set_w; + pix->height = set_h; +sensor_s_fmt_end: + return ret; } static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) diff --git a/drivers/media/video/ov5642_af_firmware.c b/drivers/media/video/ov5642_af_firmware.c index 0d742eaf9d29..7c7649cf9d6a 100644 --- a/drivers/media/video/ov5642_af_firmware.c +++ b/drivers/media/video/ov5642_af_firmware.c @@ -9,12 +9,16 @@ */ #include "ov5642.h" - +/* + * A3907 is compatible with AD5820 + */ #define VCM_DRIVER_A3907 0 #define VCM_DRIVER_AD5820 1 -#define VCM_DRIVER VCM_DRIVER_A3907 +#define VCM_DRIVER_DW9710 2 +#define VCM_DRIVER VCM_DRIVER_AD5820 #if (VCM_DRIVER == VCM_DRIVER_A3907) +/* Not support const-focus */ struct reginfo sensor_af_firmware[] = { {0x3000,0x20}, @@ -5672,5 +5676,11800 @@ struct reginfo sensor_af_firmware[] = {0x3000,0x00}, {0x0000,0x00} }; +#elif (VCM_DRIVER == VCM_DRIVER_AD5820) +/* support const-focus */ +struct reginfo sensor_af_firmware[] = +{ + {0x3000,0x20}, + {0x8000,0x02}, + {0x8001,0x00}, + {0x8002,0x06}, + {0x8003,0x02}, + {0x8004,0x0c}, + {0x8005,0xa4}, + {0x8006,0x78}, + {0x8007,0x7f}, + {0x8008,0xe4}, + {0x8009,0xf6}, + {0x800a,0xd8}, + {0x800b,0xfd}, + {0x800c,0x75}, + {0x800d,0x81}, + {0x800e,0x7e}, + {0x800f,0x02}, + {0x8010,0x14}, + {0x8011,0xc7}, + {0x8012,0x00}, + {0x8013,0x02}, + {0x8014,0x15}, + {0x8015,0x13}, + {0x8016,0xe0}, + {0x8017,0xf5}, + {0x8018,0x72}, + {0x8019,0xa3}, + {0x801a,0xe0}, + {0x801b,0xf5}, + {0x801c,0x73}, + {0x801d,0xae}, + {0x801e,0x6a}, + {0x801f,0xe4}, + {0x8020,0x85}, + {0x8021,0x6b}, + {0x8022,0x55}, + {0x8023,0x8e}, + {0x8024,0x54}, + {0x8025,0xf5}, + {0x8026,0x53}, + {0x8027,0xf5}, + {0x8028,0x52}, + {0x8029,0xab}, + {0x802a,0x55}, + {0x802b,0xaa}, + {0x802c,0x54}, + {0x802d,0xa9}, + {0x802e,0x53}, + {0x802f,0xa8}, + {0x8030,0x52}, + {0x8031,0xaf}, + {0x8032,0x2c}, + {0x8033,0xfc}, + {0x8034,0xfd}, + {0x8035,0xfe}, + {0x8036,0x12}, + {0x8037,0x08}, + {0x8038,0x98}, + {0x8039,0x8f}, + {0x803a,0x55}, + {0x803b,0x8e}, + {0x803c,0x54}, + {0x803d,0x8d}, + {0x803e,0x53}, + {0x803f,0x8c}, + {0x8040,0x52}, + {0x8041,0xaf}, + {0x8042,0x55}, + {0x8043,0xae}, + {0x8044,0x54}, + {0x8045,0xad}, + {0x8046,0x53}, + {0x8047,0xac}, + {0x8048,0x52}, + {0x8049,0x8f}, + {0x804a,0x2b}, + {0x804b,0x8e}, + {0x804c,0x2a}, + {0x804d,0x8d}, + {0x804e,0x29}, + {0x804f,0x8c}, + {0x8050,0x28}, + {0x8051,0xae}, + {0x8052,0x6c}, + {0x8053,0xe4}, + {0x8054,0x85}, + {0x8055,0x6d}, + {0x8056,0x55}, + {0x8057,0x8e}, + {0x8058,0x54}, + {0x8059,0xf5}, + {0x805a,0x53}, + {0x805b,0xf5}, + {0x805c,0x52}, + {0x805d,0xab}, + {0x805e,0x55}, + {0x805f,0xaa}, + {0x8060,0x54}, + {0x8061,0xa9}, + {0x8062,0x53}, + {0x8063,0xa8}, + {0x8064,0x52}, + {0x8065,0xaf}, + {0x8066,0x2d}, + {0x8067,0xfc}, + {0x8068,0xfd}, + {0x8069,0xfe}, + {0x806a,0x12}, + {0x806b,0x08}, + {0x806c,0x98}, + {0x806d,0x8f}, + {0x806e,0x55}, + {0x806f,0x8e}, + {0x8070,0x54}, + {0x8071,0x8d}, + {0x8072,0x53}, + {0x8073,0x8c}, + {0x8074,0x52}, + {0x8075,0xe5}, + {0x8076,0x2b}, + {0x8077,0x25}, + {0x8078,0x55}, + {0x8079,0xf5}, + {0x807a,0x2b}, + {0x807b,0xe5}, + {0x807c,0x2a}, + {0x807d,0x35}, + {0x807e,0x54}, + {0x807f,0xf5}, + {0x8080,0x2a}, + {0x8081,0xe5}, + {0x8082,0x29}, + {0x8083,0x35}, + {0x8084,0x53}, + {0x8085,0xf5}, + {0x8086,0x29}, + {0x8087,0xe5}, + {0x8088,0x28}, + {0x8089,0x35}, + {0x808a,0x52}, + {0x808b,0xf5}, + {0x808c,0x28}, + {0x808d,0xae}, + {0x808e,0x6e}, + {0x808f,0xe4}, + {0x8090,0x85}, + {0x8091,0x6f}, + {0x8092,0x55}, + {0x8093,0x8e}, + {0x8094,0x54}, + {0x8095,0xf5}, + {0x8096,0x53}, + {0x8097,0xf5}, + {0x8098,0x52}, + {0x8099,0xab}, + {0x809a,0x55}, + {0x809b,0xaa}, + {0x809c,0x54}, + {0x809d,0xa9}, + {0x809e,0x53}, + {0x809f,0xa8}, + {0x80a0,0x52}, + {0x80a1,0xaf}, + {0x80a2,0x2e}, + {0x80a3,0xfc}, + {0x80a4,0xfd}, + {0x80a5,0xfe}, + {0x80a6,0x12}, + {0x80a7,0x08}, + {0x80a8,0x98}, + {0x80a9,0x8f}, + {0x80aa,0x55}, + {0x80ab,0x8e}, + {0x80ac,0x54}, + {0x80ad,0x8d}, + {0x80ae,0x53}, + {0x80af,0x8c}, + {0x80b0,0x52}, + {0x80b1,0xe5}, + {0x80b2,0x2b}, + {0x80b3,0x25}, + {0x80b4,0x55}, + {0x80b5,0xf5}, + {0x80b6,0x2b}, + {0x80b7,0xe5}, + {0x80b8,0x2a}, + {0x80b9,0x35}, + {0x80ba,0x54}, + {0x80bb,0xf5}, + {0x80bc,0x2a}, + {0x80bd,0xe5}, + {0x80be,0x29}, + {0x80bf,0x35}, + {0x80c0,0x53}, + {0x80c1,0xf5}, + {0x80c2,0x29}, + {0x80c3,0xe5}, + {0x80c4,0x28}, + {0x80c5,0x35}, + {0x80c6,0x52}, + {0x80c7,0xf5}, + {0x80c8,0x28}, + {0x80c9,0xae}, + {0x80ca,0x70}, + {0x80cb,0xe4}, + {0x80cc,0x85}, + {0x80cd,0x71}, + {0x80ce,0x55}, + {0x80cf,0x8e}, + {0x80d0,0x54}, + {0x80d1,0xf5}, + {0x80d2,0x53}, + {0x80d3,0xf5}, + {0x80d4,0x52}, + {0x80d5,0xab}, + {0x80d6,0x55}, + {0x80d7,0xaa}, + {0x80d8,0x54}, + {0x80d9,0xa9}, + {0x80da,0x53}, + {0x80db,0xa8}, + {0x80dc,0x52}, + {0x80dd,0xaf}, + {0x80de,0x2f}, + {0x80df,0xfc}, + {0x80e0,0xfd}, + {0x80e1,0xfe}, + {0x80e2,0x12}, + {0x80e3,0x08}, + {0x80e4,0x98}, + {0x80e5,0x8f}, + {0x80e6,0x55}, + {0x80e7,0x8e}, + {0x80e8,0x54}, + {0x80e9,0x8d}, + {0x80ea,0x53}, + {0x80eb,0x8c}, + {0x80ec,0x52}, + {0x80ed,0xe5}, + {0x80ee,0x2b}, + {0x80ef,0x25}, + {0x80f0,0x55}, + {0x80f1,0xf5}, + {0x80f2,0x2b}, + {0x80f3,0xe5}, + {0x80f4,0x2a}, + {0x80f5,0x35}, + {0x80f6,0x54}, + {0x80f7,0xf5}, + {0x80f8,0x2a}, + {0x80f9,0xe5}, + {0x80fa,0x29}, + {0x80fb,0x35}, + {0x80fc,0x53}, + {0x80fd,0xf5}, + {0x80fe,0x29}, + {0x80ff,0xe5}, + {0x8100,0x28}, + {0x8101,0x35}, + {0x8102,0x52}, + {0x8103,0xf5}, + {0x8104,0x28}, + {0x8105,0xae}, + {0x8106,0x72}, + {0x8107,0xe4}, + {0x8108,0x85}, + {0x8109,0x73}, + {0x810a,0x55}, + {0x810b,0x8e}, + {0x810c,0x54}, + {0x810d,0xf5}, + {0x810e,0x53}, + {0x810f,0xf5}, + {0x8110,0x52}, + {0x8111,0xab}, + {0x8112,0x55}, + {0x8113,0xaa}, + {0x8114,0x54}, + {0x8115,0xa9}, + {0x8116,0x53}, + {0x8117,0xa8}, + {0x8118,0x52}, + {0x8119,0xaf}, + {0x811a,0x30}, + {0x811b,0xfc}, + {0x811c,0xfd}, + {0x811d,0xfe}, + {0x811e,0x12}, + {0x811f,0x08}, + {0x8120,0x98}, + {0x8121,0x8f}, + {0x8122,0x55}, + {0x8123,0x8e}, + {0x8124,0x54}, + {0x8125,0x8d}, + {0x8126,0x53}, + {0x8127,0x8c}, + {0x8128,0x52}, + {0x8129,0xe5}, + {0x812a,0x2b}, + {0x812b,0x25}, + {0x812c,0x55}, + {0x812d,0xf5}, + {0x812e,0x2b}, + {0x812f,0xe5}, + {0x8130,0x2a}, + {0x8131,0x35}, + {0x8132,0x54}, + {0x8133,0xf5}, + {0x8134,0x2a}, + {0x8135,0xe5}, + {0x8136,0x29}, + {0x8137,0x35}, + {0x8138,0x53}, + {0x8139,0xf5}, + {0x813a,0x29}, + {0x813b,0xe5}, + {0x813c,0x28}, + {0x813d,0x35}, + {0x813e,0x52}, + {0x813f,0xf5}, + {0x8140,0x28}, + {0x8141,0x22}, + {0x8142,0xab}, + {0x8143,0x0d}, + {0x8144,0xaa}, + {0x8145,0x0c}, + {0x8146,0xa9}, + {0x8147,0x0b}, + {0x8148,0xa8}, + {0x8149,0x0a}, + {0x814a,0xfc}, + {0x814b,0xfd}, + {0x814c,0xfe}, + {0x814d,0x12}, + {0x814e,0x08}, + {0x814f,0x98}, + {0x8150,0x8f}, + {0x8151,0x0d}, + {0x8152,0x8e}, + {0x8153,0x0c}, + {0x8154,0x8d}, + {0x8155,0x0b}, + {0x8156,0x8c}, + {0x8157,0x0a}, + {0x8158,0x7b}, + {0x8159,0x40}, + {0x815a,0xe4}, + {0x815b,0xfa}, + {0x815c,0xf9}, + {0x815d,0xf8}, + {0x815e,0x12}, + {0x815f,0x09}, + {0x8160,0x23}, + {0x8161,0x8f}, + {0x8162,0x0d}, + {0x8163,0x8e}, + {0x8164,0x0c}, + {0x8165,0x8d}, + {0x8166,0x0b}, + {0x8167,0x8c}, + {0x8168,0x0a}, + {0x8169,0x22}, + {0x816a,0xd2}, + {0x816b,0x29}, + {0x816c,0x90}, + {0x816d,0x30}, + {0x816e,0x1b}, + {0x816f,0xe5}, + {0x8170,0x25}, + {0x8171,0xf0}, + {0x8172,0x22}, + {0x8173,0x85}, + {0x8174,0x49}, + {0x8175,0x82}, + {0x8176,0x85}, + {0x8177,0x48}, + {0x8178,0x83}, + {0x8179,0xe5}, + {0x817a,0x7c}, + {0x817b,0x75}, + {0x817c,0xf0}, + {0x817d,0x02}, + {0x817e,0x12}, + {0x817f,0x09}, + {0x8180,0xeb}, + {0x8181,0xe4}, + {0x8182,0x93}, + {0x8183,0xfe}, + {0x8184,0x74}, + {0x8185,0x01}, + {0x8186,0x93}, + {0x8187,0xff}, + {0x8188,0x85}, + {0x8189,0x49}, + {0x818a,0x82}, + {0x818b,0x85}, + {0x818c,0x48}, + {0x818d,0x83}, + {0x818e,0xe4}, + {0x818f,0x93}, + {0x8190,0xfc}, + {0x8191,0x74}, + {0x8192,0x01}, + {0x8193,0x93}, + {0x8194,0xfd}, + {0x8195,0xc3}, + {0x8196,0xef}, + {0x8197,0x9d}, + {0x8198,0xff}, + {0x8199,0xee}, + {0x819a,0x9c}, + {0x819b,0x22}, + {0x819c,0xfe}, + {0x819d,0xe4}, + {0x819e,0xfc}, + {0x819f,0xfd}, + {0x81a0,0xe5}, + {0x81a1,0x3f}, + {0x81a2,0x2f}, + {0x81a3,0xf5}, + {0x81a4,0x3f}, + {0x81a5,0xe5}, + {0x81a6,0x3e}, + {0x81a7,0x3e}, + {0x81a8,0xf5}, + {0x81a9,0x3e}, + {0x81aa,0xed}, + {0x81ab,0x35}, + {0x81ac,0x3d}, + {0x81ad,0xf5}, + {0x81ae,0x3d}, + {0x81af,0xec}, + {0x81b0,0x35}, + {0x81b1,0x3c}, + {0x81b2,0xf5}, + {0x81b3,0x3c}, + {0x81b4,0xaf}, + {0x81b5,0x3f}, + {0x81b6,0xae}, + {0x81b7,0x3e}, + {0x81b8,0xfc}, + {0x81b9,0xad}, + {0x81ba,0x3d}, + {0x81bb,0x78}, + {0x81bc,0x08}, + {0x81bd,0x12}, + {0x81be,0x09}, + {0x81bf,0xc8}, + {0x81c0,0x8f}, + {0x81c1,0x3f}, + {0x81c2,0x8e}, + {0x81c3,0x3e}, + {0x81c4,0x8d}, + {0x81c5,0x3d}, + {0x81c6,0x8c}, + {0x81c7,0x3c}, + {0x81c8,0x22}, + {0x81c9,0xaf}, + {0x81ca,0x2b}, + {0x81cb,0xae}, + {0x81cc,0x2a}, + {0x81cd,0xad}, + {0x81ce,0x29}, + {0x81cf,0xac}, + {0x81d0,0x28}, + {0x81d1,0x78}, + {0x81d2,0x06}, + {0x81d3,0x12}, + {0x81d4,0x09}, + {0x81d5,0xb5}, + {0x81d6,0x8f}, + {0x81d7,0x2b}, + {0x81d8,0x8e}, + {0x81d9,0x2a}, + {0x81da,0x8d}, + {0x81db,0x29}, + {0x81dc,0x8c}, + {0x81dd,0x28}, + {0x81de,0xd3}, + {0x81df,0xe5}, + {0x81e0,0x29}, + {0x81e1,0x94}, + {0x81e2,0x00}, + {0x81e3,0xe5}, + {0x81e4,0x28}, + {0x81e5,0x94}, + {0x81e6,0x00}, + {0x81e7,0x22}, + {0x81e8,0xe5}, + {0x81e9,0x0b}, + {0x81ea,0x24}, + {0x81eb,0x01}, + {0x81ec,0xff}, + {0x81ed,0xe4}, + {0x81ee,0x33}, + {0x81ef,0xfe}, + {0x81f0,0x22}, + {0x81f1,0x12}, + {0x81f2,0x08}, + {0x81f3,0x98}, + {0x81f4,0x8f}, + {0x81f5,0x69}, + {0x81f6,0x8e}, + {0x81f7,0x68}, + {0x81f8,0x8d}, + {0x81f9,0x67}, + {0x81fa,0x8c}, + {0x81fb,0x66}, + {0x81fc,0xaf}, + {0x81fd,0x69}, + {0x81fe,0xae}, + {0x81ff,0x68}, + {0x8200,0xad}, + {0x8201,0x67}, + {0x8202,0xac}, + {0x8203,0x66}, + {0x8204,0x22}, + {0x8205,0xe0}, + {0x8206,0x44}, + {0x8207,0x01}, + {0x8208,0xf0}, + {0x8209,0xe0}, + {0x820a,0x44}, + {0x820b,0x02}, + {0x820c,0xf0}, + {0x820d,0xe0}, + {0x820e,0x44}, + {0x820f,0x04}, + {0x8210,0xf0}, + {0x8211,0x22}, + {0x8212,0xd2}, + {0x8213,0x09}, + {0x8214,0x90}, + {0x8215,0x30}, + {0x8216,0x18}, + {0x8217,0xe5}, + {0x8218,0x21}, + {0x8219,0xf0}, + {0x821a,0x22}, + {0x821b,0xe4}, + {0x821c,0x85}, + {0x821d,0x11}, + {0x821e,0x0d}, + {0x821f,0x85}, + {0x8220,0x10}, + {0x8221,0x0c}, + {0x8222,0xf5}, + {0x8223,0x0b}, + {0x8224,0xf5}, + {0x8225,0x0a}, + {0x8226,0xab}, + {0x8227,0x0d}, + {0x8228,0xaa}, + {0x8229,0x0c}, + {0x822a,0xa9}, + {0x822b,0x0b}, + {0x822c,0xa8}, + {0x822d,0x0a}, + {0x822e,0x22}, + {0x822f,0x90}, + {0x8230,0x30}, + {0x8231,0x42}, + {0x8232,0xe0}, + {0x8233,0xf5}, + {0x8234,0x22}, + {0x8235,0x75}, + {0x8236,0x51}, + {0x8237,0x0a}, + {0x8238,0x22}, + {0x8239,0x85}, + {0x823a,0x49}, + {0x823b,0x82}, + {0x823c,0x85}, + {0x823d,0x48}, + {0x823e,0x83}, + {0x823f,0x22}, + {0x8240,0xf5}, + {0x8241,0x82}, + {0x8242,0xe4}, + {0x8243,0x3a}, + {0x8244,0xf5}, + {0x8245,0x83}, + {0x8246,0x02}, + {0x8247,0x09}, + {0x8248,0xdb}, + {0x8249,0x8f}, + {0x824a,0x0a}, + {0x824b,0x74}, + {0x824c,0x4a}, + {0x824d,0x2f}, + {0x824e,0xf8}, + {0x824f,0xe6}, + {0x8250,0x22}, + {0x8251,0xc2}, + {0x8252,0x07}, + {0x8253,0xc2}, + {0x8254,0x06}, + {0x8255,0xc2}, + {0x8256,0x02}, + {0x8257,0xc2}, + {0x8258,0x01}, + {0x8259,0xc2}, + {0x825a,0x00}, + {0x825b,0xc2}, + {0x825c,0x03}, + {0x825d,0xd2}, + {0x825e,0x04}, + {0x825f,0x22}, + {0x8260,0xe5}, + {0x8261,0x16}, + {0x8262,0x25}, + {0x8263,0xe0}, + {0x8264,0x25}, + {0x8265,0xe0}, + {0x8266,0x22}, + {0x8267,0x12}, + {0x8268,0x09}, + {0x8269,0x23}, + {0x826a,0x8f}, + {0x826b,0x69}, + {0x826c,0x8e}, + {0x826d,0x68}, + {0x826e,0x8d}, + {0x826f,0x67}, + {0x8270,0x8c}, + {0x8271,0x66}, + {0x8272,0x22}, + {0x8273,0xe4}, + {0x8274,0x85}, + {0x8275,0x0f}, + {0x8276,0x0d}, + {0x8277,0x85}, + {0x8278,0x0e}, + {0x8279,0x0c}, + {0x827a,0xf5}, + {0x827b,0x0b}, + {0x827c,0xf5}, + {0x827d,0x0a}, + {0x827e,0x22}, + {0x827f,0x90}, + {0x8280,0x11}, + {0x8281,0x67}, + {0x8282,0xe4}, + {0x8283,0x93}, + {0x8284,0xff}, + {0x8285,0x90}, + {0x8286,0x30}, + {0x8287,0x0a}, + {0x8288,0xe0}, + {0x8289,0x22}, + {0x828a,0xc2}, + {0x828b,0x02}, + {0x828c,0xc2}, + {0x828d,0x01}, + {0x828e,0xd2}, + {0x828f,0x00}, + {0x8290,0xc2}, + {0x8291,0x03}, + {0x8292,0xc2}, + {0x8293,0x04}, + {0x8294,0x22}, + {0x8295,0x75}, + {0x8296,0xf0}, + {0x8297,0x02}, + {0x8298,0x02}, + {0x8299,0x09}, + {0x829a,0xeb}, + {0x829b,0xd2}, + {0x829c,0x02}, + {0x829d,0xd2}, + {0x829e,0x01}, + {0x829f,0xc2}, + {0x82a0,0x00}, + {0x82a1,0x22}, + {0x82a2,0x74}, + {0x82a3,0x4a}, + {0x82a4,0x25}, + {0x82a5,0x0a}, + {0x82a6,0xf8}, + {0x82a7,0xe6}, + {0x82a8,0x22}, + {0x82a9,0xd3}, + {0x82aa,0xe5}, + {0x82ab,0x0b}, + {0x82ac,0x94}, + {0x82ad,0xff}, + {0x82ae,0xe5}, + {0x82af,0x0a}, + {0x82b0,0x94}, + {0x82b1,0x00}, + {0x82b2,0x22}, + {0x82b3,0xd3}, + {0x82b4,0xe5}, + {0x82b5,0x69}, + {0x82b6,0x94}, + {0x82b7,0xff}, + {0x82b8,0xe5}, + {0x82b9,0x68}, + {0x82ba,0x94}, + {0x82bb,0x03}, + {0x82bc,0x22}, + {0x82bd,0x30}, + {0x82be,0x18}, + {0x82bf,0x4d}, + {0x82c0,0x20}, + {0x82c1,0x19}, + {0x82c2,0x4a}, + {0x82c3,0x75}, + {0x82c4,0x0a}, + {0x82c5,0x02}, + {0x82c6,0x12}, + {0x82c7,0x02}, + {0x82c8,0xa2}, + {0x82c9,0xff}, + {0x82ca,0xe5}, + {0x82cb,0x4a}, + {0x82cc,0xd3}, + {0x82cd,0x9f}, + {0x82ce,0x40}, + {0x82cf,0x04}, + {0x82d0,0x7f}, + {0x82d1,0x00}, + {0x82d2,0x80}, + {0x82d3,0x02}, + {0x82d4,0xaf}, + {0x82d5,0x0a}, + {0x82d6,0x12}, + {0x82d7,0x02}, + {0x82d8,0x49}, + {0x82d9,0xff}, + {0x82da,0xe5}, + {0x82db,0x4b}, + {0x82dc,0xd3}, + {0x82dd,0x9f}, + {0x82de,0x40}, + {0x82df,0x04}, + {0x82e0,0x7f}, + {0x82e1,0x01}, + {0x82e2,0x80}, + {0x82e3,0x02}, + {0x82e4,0xaf}, + {0x82e5,0x0a}, + {0x82e6,0x12}, + {0x82e7,0x02}, + {0x82e8,0x49}, + {0x82e9,0xff}, + {0x82ea,0xe5}, + {0x82eb,0x4d}, + {0x82ec,0xd3}, + {0x82ed,0x9f}, + {0x82ee,0x40}, + {0x82ef,0x04}, + {0x82f0,0x7f}, + {0x82f1,0x03}, + {0x82f2,0x80}, + {0x82f3,0x02}, + {0x82f4,0xaf}, + {0x82f5,0x0a}, + {0x82f6,0x12}, + {0x82f7,0x02}, + {0x82f8,0x49}, + {0x82f9,0xff}, + {0x82fa,0xe5}, + {0x82fb,0x4e}, + {0x82fc,0xd3}, + {0x82fd,0x9f}, + {0x82fe,0x40}, + {0x82ff,0x04}, + {0x8300,0x7f}, + {0x8301,0x04}, + {0x8302,0x80}, + {0x8303,0x02}, + {0x8304,0xaf}, + {0x8305,0x0a}, + {0x8306,0x12}, + {0x8307,0x02}, + {0x8308,0x49}, + {0x8309,0xf5}, + {0x830a,0x0b}, + {0x830b,0x80}, + {0x830c,0x06}, + {0x830d,0x85}, + {0x830e,0x79}, + {0x830f,0x0a}, + {0x8310,0x85}, + {0x8311,0x4f}, + {0x8312,0x0b}, + {0x8313,0x7f}, + {0x8314,0x01}, + {0x8315,0xe4}, + {0x8316,0xfe}, + {0x8317,0x12}, + {0x8318,0x02}, + {0x8319,0xa2}, + {0x831a,0xfd}, + {0x831b,0xe5}, + {0x831c,0x0b}, + {0x831d,0xc3}, + {0x831e,0x9d}, + {0x831f,0x50}, + {0x8320,0x04}, + {0x8321,0x7d}, + {0x8322,0x01}, + {0x8323,0x80}, + {0x8324,0x02}, + {0x8325,0x7d}, + {0x8326,0xff}, + {0x8327,0xac}, + {0x8328,0x0b}, + {0x8329,0xe5}, + {0x832a,0x4e}, + {0x832b,0xb5}, + {0x832c,0x0b}, + {0x832d,0x03}, + {0x832e,0xd3}, + {0x832f,0x80}, + {0x8330,0x01}, + {0x8331,0xc3}, + {0x8332,0x92}, + {0x8333,0x1f}, + {0x8334,0xe5}, + {0x8335,0x4d}, + {0x8336,0xb5}, + {0x8337,0x0b}, + {0x8338,0x03}, + {0x8339,0xd3}, + {0x833a,0x80}, + {0x833b,0x01}, + {0x833c,0xc3}, + {0x833d,0x92}, + {0x833e,0x1e}, + {0x833f,0xe5}, + {0x8340,0x4c}, + {0x8341,0xb5}, + {0x8342,0x0b}, + {0x8343,0x03}, + {0x8344,0xd3}, + {0x8345,0x80}, + {0x8346,0x01}, + {0x8347,0xc3}, + {0x8348,0x92}, + {0x8349,0x1d}, + {0x834a,0xe5}, + {0x834b,0x4b}, + {0x834c,0xb5}, + {0x834d,0x0b}, + {0x834e,0x03}, + {0x834f,0xd3}, + {0x8350,0x80}, + {0x8351,0x01}, + {0x8352,0xc3}, + {0x8353,0x92}, + {0x8354,0x1c}, + {0x8355,0xe5}, + {0x8356,0x4a}, + {0x8357,0xb5}, + {0x8358,0x0b}, + {0x8359,0x03}, + {0x835a,0xd3}, + {0x835b,0x80}, + {0x835c,0x01}, + {0x835d,0xc3}, + {0x835e,0x92}, + {0x835f,0x1b}, + {0x8360,0xe5}, + {0x8361,0x30}, + {0x8362,0xd3}, + {0x8363,0x94}, + {0x8364,0x00}, + {0x8365,0x40}, + {0x8366,0x04}, + {0x8367,0xa2}, + {0x8368,0x1f}, + {0x8369,0x80}, + {0x836a,0x01}, + {0x836b,0xc3}, + {0x836c,0x92}, + {0x836d,0x1f}, + {0x836e,0xe5}, + {0x836f,0x2f}, + {0x8370,0xd3}, + {0x8371,0x94}, + {0x8372,0x00}, + {0x8373,0x40}, + {0x8374,0x04}, + {0x8375,0xa2}, + {0x8376,0x1e}, + {0x8377,0x80}, + {0x8378,0x01}, + {0x8379,0xc3}, + {0x837a,0x92}, + {0x837b,0x1e}, + {0x837c,0xe5}, + {0x837d,0x2e}, + {0x837e,0xd3}, + {0x837f,0x94}, + {0x8380,0x00}, + {0x8381,0x40}, + {0x8382,0x04}, + {0x8383,0xa2}, + {0x8384,0x1d}, + {0x8385,0x80}, + {0x8386,0x01}, + {0x8387,0xc3}, + {0x8388,0x92}, + {0x8389,0x1d}, + {0x838a,0xe5}, + {0x838b,0x2d}, + {0x838c,0xd3}, + {0x838d,0x94}, + {0x838e,0x00}, + {0x838f,0x40}, + {0x8390,0x04}, + {0x8391,0xa2}, + {0x8392,0x1c}, + {0x8393,0x80}, + {0x8394,0x01}, + {0x8395,0xc3}, + {0x8396,0x92}, + {0x8397,0x1c}, + {0x8398,0xe5}, + {0x8399,0x2c}, + {0x839a,0xd3}, + {0x839b,0x94}, + {0x839c,0x00}, + {0x839d,0x40}, + {0x839e,0x04}, + {0x839f,0xa2}, + {0x83a0,0x1b}, + {0x83a1,0x80}, + {0x83a2,0x01}, + {0x83a3,0xc3}, + {0x83a4,0x92}, + {0x83a5,0x1b}, + {0x83a6,0xe5}, + {0x83a7,0x23}, + {0x83a8,0x54}, + {0x83a9,0xf8}, + {0x83aa,0x70}, + {0x83ab,0x5b}, + {0x83ac,0xbf}, + {0x83ad,0x01}, + {0x83ae,0x08}, + {0x83af,0xed}, + {0x83b0,0xf4}, + {0x83b1,0x04}, + {0x83b2,0xfd}, + {0x83b3,0x7f}, + {0x83b4,0x02}, + {0x83b5,0x80}, + {0x83b6,0x06}, + {0x83b7,0xbf}, + {0x83b8,0x02}, + {0x83b9,0x02}, + {0x83ba,0x7f}, + {0x83bb,0x01}, + {0x83bc,0x0e}, + {0x83bd,0xd3}, + {0x83be,0xed}, + {0x83bf,0x64}, + {0x83c0,0x80}, + {0x83c1,0x94}, + {0x83c2,0x80}, + {0x83c3,0x40}, + {0x83c4,0x18}, + {0x83c5,0xec}, + {0x83c6,0x2e}, + {0x83c7,0xf5}, + {0x83c8,0x0b}, + {0x83c9,0xd3}, + {0x83ca,0x95}, + {0x83cb,0x7c}, + {0x83cc,0x40}, + {0x83cd,0x2c}, + {0x83ce,0x7d}, + {0x83cf,0xff}, + {0x83d0,0xef}, + {0x83d1,0x60}, + {0x83d2,0x04}, + {0x83d3,0x7b}, + {0x83d4,0x00}, + {0x83d5,0x80}, + {0x83d6,0x02}, + {0x83d7,0x7b}, + {0x83d8,0x03}, + {0x83d9,0xaf}, + {0x83da,0x03}, + {0x83db,0x80}, + {0x83dc,0x18}, + {0x83dd,0xec}, + {0x83de,0xc3}, + {0x83df,0x9e}, + {0x83e0,0x50}, + {0x83e1,0x13}, + {0x83e2,0x7d}, + {0x83e3,0x01}, + {0x83e4,0xef}, + {0x83e5,0x60}, + {0x83e6,0x04}, + {0x83e7,0x7b}, + {0x83e8,0x00}, + {0x83e9,0x80}, + {0x83ea,0x02}, + {0x83eb,0x7b}, + {0x83ec,0x03}, + {0x83ed,0xaf}, + {0x83ee,0x03}, + {0x83ef,0xec}, + {0x83f0,0x2e}, + {0x83f1,0xf5}, + {0x83f2,0x0b}, + {0x83f3,0x80}, + {0x83f4,0x05}, + {0x83f5,0xc3}, + {0x83f6,0xec}, + {0x83f7,0x9e}, + {0x83f8,0xf5}, + {0x83f9,0x0b}, + {0x83fa,0xef}, + {0x83fb,0x64}, + {0x83fc,0x03}, + {0x83fd,0x60}, + {0x83fe,0x03}, + {0x83ff,0x02}, + {0x8400,0x03}, + {0x8401,0x29}, + {0x8402,0x12}, + {0x8403,0x02}, + {0x8404,0xa2}, + {0x8405,0xf5}, + {0x8406,0x0b}, + {0x8407,0x12}, + {0x8408,0x01}, + {0x8409,0xe8}, + {0x840a,0xe5}, + {0x840b,0x4e}, + {0x840c,0xb5}, + {0x840d,0x07}, + {0x840e,0x07}, + {0x840f,0xe4}, + {0x8410,0xb5}, + {0x8411,0x06}, + {0x8412,0x03}, + {0x8413,0xd3}, + {0x8414,0x80}, + {0x8415,0x02}, + {0x8416,0xa2}, + {0x8417,0x1f}, + {0x8418,0x92}, + {0x8419,0x1f}, + {0x841a,0xe5}, + {0x841b,0x4d}, + {0x841c,0xb5}, + {0x841d,0x07}, + {0x841e,0x07}, + {0x841f,0xe4}, + {0x8420,0xb5}, + {0x8421,0x06}, + {0x8422,0x03}, + {0x8423,0xd3}, + {0x8424,0x80}, + {0x8425,0x02}, + {0x8426,0xa2}, + {0x8427,0x1e}, + {0x8428,0x92}, + {0x8429,0x1e}, + {0x842a,0x12}, + {0x842b,0x01}, + {0x842c,0xe8}, + {0x842d,0xe5}, + {0x842e,0x4c}, + {0x842f,0xb5}, + {0x8430,0x07}, + {0x8431,0x07}, + {0x8432,0xe4}, + {0x8433,0xb5}, + {0x8434,0x06}, + {0x8435,0x03}, + {0x8436,0xd3}, + {0x8437,0x80}, + {0x8438,0x02}, + {0x8439,0xa2}, + {0x843a,0x1d}, + {0x843b,0x92}, + {0x843c,0x1d}, + {0x843d,0xe5}, + {0x843e,0x4b}, + {0x843f,0xb5}, + {0x8440,0x07}, + {0x8441,0x07}, + {0x8442,0xe4}, + {0x8443,0xb5}, + {0x8444,0x06}, + {0x8445,0x03}, + {0x8446,0xd3}, + {0x8447,0x80}, + {0x8448,0x02}, + {0x8449,0xa2}, + {0x844a,0x1c}, + {0x844b,0x92}, + {0x844c,0x1c}, + {0x844d,0x12}, + {0x844e,0x01}, + {0x844f,0xe8}, + {0x8450,0xe5}, + {0x8451,0x4a}, + {0x8452,0xb5}, + {0x8453,0x07}, + {0x8454,0x07}, + {0x8455,0xe4}, + {0x8456,0xb5}, + {0x8457,0x06}, + {0x8458,0x03}, + {0x8459,0xd3}, + {0x845a,0x80}, + {0x845b,0x02}, + {0x845c,0xa2}, + {0x845d,0x1b}, + {0x845e,0x92}, + {0x845f,0x1b}, + {0x8460,0xe5}, + {0x8461,0x4e}, + {0x8462,0x12}, + {0x8463,0x01}, + {0x8464,0xea}, + {0x8465,0xad}, + {0x8466,0x0b}, + {0x8467,0x7c}, + {0x8468,0x00}, + {0x8469,0xef}, + {0x846a,0xb5}, + {0x846b,0x05}, + {0x846c,0x07}, + {0x846d,0xec}, + {0x846e,0xb5}, + {0x846f,0x06}, + {0x8470,0x03}, + {0x8471,0xd3}, + {0x8472,0x80}, + {0x8473,0x02}, + {0x8474,0xa2}, + {0x8475,0x1f}, + {0x8476,0x92}, + {0x8477,0x1f}, + {0x8478,0xe5}, + {0x8479,0x4d}, + {0x847a,0x12}, + {0x847b,0x01}, + {0x847c,0xea}, + {0x847d,0xef}, + {0x847e,0xb5}, + {0x847f,0x05}, + {0x8480,0x07}, + {0x8481,0xee}, + {0x8482,0xb5}, + {0x8483,0x04}, + {0x8484,0x03}, + {0x8485,0xd3}, + {0x8486,0x80}, + {0x8487,0x02}, + {0x8488,0xa2}, + {0x8489,0x1e}, + {0x848a,0x92}, + {0x848b,0x1e}, + {0x848c,0xe5}, + {0x848d,0x4c}, + {0x848e,0x12}, + {0x848f,0x01}, + {0x8490,0xea}, + {0x8491,0xad}, + {0x8492,0x0b}, + {0x8493,0x7c}, + {0x8494,0x00}, + {0x8495,0xef}, + {0x8496,0xb5}, + {0x8497,0x05}, + {0x8498,0x07}, + {0x8499,0xec}, + {0x849a,0xb5}, + {0x849b,0x06}, + {0x849c,0x03}, + {0x849d,0xd3}, + {0x849e,0x80}, + {0x849f,0x02}, + {0x84a0,0xa2}, + {0x84a1,0x1d}, + {0x84a2,0x92}, + {0x84a3,0x1d}, + {0x84a4,0xe5}, + {0x84a5,0x4b}, + {0x84a6,0x12}, + {0x84a7,0x01}, + {0x84a8,0xea}, + {0x84a9,0xef}, + {0x84aa,0xb5}, + {0x84ab,0x05}, + {0x84ac,0x07}, + {0x84ad,0xee}, + {0x84ae,0xb5}, + {0x84af,0x04}, + {0x84b0,0x03}, + {0x84b1,0xd3}, + {0x84b2,0x80}, + {0x84b3,0x02}, + {0x84b4,0xa2}, + {0x84b5,0x1c}, + {0x84b6,0x92}, + {0x84b7,0x1c}, + {0x84b8,0xe5}, + {0x84b9,0x4a}, + {0x84ba,0x12}, + {0x84bb,0x01}, + {0x84bc,0xea}, + {0x84bd,0x7c}, + {0x84be,0x00}, + {0x84bf,0xef}, + {0x84c0,0xb5}, + {0x84c1,0x0b}, + {0x84c2,0x07}, + {0x84c3,0xec}, + {0x84c4,0xb5}, + {0x84c5,0x06}, + {0x84c6,0x03}, + {0x84c7,0xd3}, + {0x84c8,0x80}, + {0x84c9,0x02}, + {0x84ca,0xa2}, + {0x84cb,0x1b}, + {0x84cc,0x92}, + {0x84cd,0x1b}, + {0x84ce,0xe5}, + {0x84cf,0x30}, + {0x84d0,0xd3}, + {0x84d1,0x94}, + {0x84d2,0x00}, + {0x84d3,0x40}, + {0x84d4,0x04}, + {0x84d5,0xa2}, + {0x84d6,0x1f}, + {0x84d7,0x80}, + {0x84d8,0x01}, + {0x84d9,0xc3}, + {0x84da,0x92}, + {0x84db,0x1f}, + {0x84dc,0xe5}, + {0x84dd,0x2f}, + {0x84de,0xd3}, + {0x84df,0x94}, + {0x84e0,0x00}, + {0x84e1,0x40}, + {0x84e2,0x04}, + {0x84e3,0xa2}, + {0x84e4,0x1e}, + {0x84e5,0x80}, + {0x84e6,0x01}, + {0x84e7,0xc3}, + {0x84e8,0x92}, + {0x84e9,0x1e}, + {0x84ea,0xe5}, + {0x84eb,0x2e}, + {0x84ec,0xd3}, + {0x84ed,0x94}, + {0x84ee,0x00}, + {0x84ef,0x40}, + {0x84f0,0x04}, + {0x84f1,0xa2}, + {0x84f2,0x1d}, + {0x84f3,0x80}, + {0x84f4,0x01}, + {0x84f5,0xc3}, + {0x84f6,0x92}, + {0x84f7,0x1d}, + {0x84f8,0xe5}, + {0x84f9,0x2d}, + {0x84fa,0xd3}, + {0x84fb,0x94}, + {0x84fc,0x00}, + {0x84fd,0x40}, + {0x84fe,0x04}, + {0x84ff,0xa2}, + {0x8500,0x1c}, + {0x8501,0x80}, + {0x8502,0x01}, + {0x8503,0xc3}, + {0x8504,0x92}, + {0x8505,0x1c}, + {0x8506,0xe5}, + {0x8507,0x2c}, + {0x8508,0xd3}, + {0x8509,0x94}, + {0x850a,0x00}, + {0x850b,0x40}, + {0x850c,0x04}, + {0x850d,0xa2}, + {0x850e,0x1b}, + {0x850f,0x80}, + {0x8510,0x01}, + {0x8511,0xc3}, + {0x8512,0x92}, + {0x8513,0x1b}, + {0x8514,0x85}, + {0x8515,0x0a}, + {0x8516,0x79}, + {0x8517,0xe5}, + {0x8518,0x7d}, + {0x8519,0xb5}, + {0x851a,0x0b}, + {0x851b,0x03}, + {0x851c,0x02}, + {0x851d,0x16}, + {0x851e,0x5f}, + {0x851f,0x85}, + {0x8520,0x0b}, + {0x8521,0x0c}, + {0x8522,0x12}, + {0x8523,0x13}, + {0x8524,0x64}, + {0x8525,0xd2}, + {0x8526,0x02}, + {0x8527,0xc2}, + {0x8528,0x01}, + {0x8529,0xd2}, + {0x852a,0x00}, + {0x852b,0x75}, + {0x852c,0x31}, + {0x852d,0x03}, + {0x852e,0x22}, + {0x852f,0xe5}, + {0x8530,0x7e}, + {0x8531,0x24}, + {0x8532,0xfe}, + {0x8533,0x60}, + {0x8534,0x27}, + {0x8535,0x14}, + {0x8536,0x60}, + {0x8537,0x31}, + {0x8538,0x24}, + {0x8539,0xf8}, + {0x853a,0x60}, + {0x853b,0x3a}, + {0x853c,0x14}, + {0x853d,0x60}, + {0x853e,0x4b}, + {0x853f,0x14}, + {0x8540,0x60}, + {0x8541,0x59}, + {0x8542,0x14}, + {0x8543,0x60}, + {0x8544,0x6a}, + {0x8545,0x24}, + {0x8546,0xfd}, + {0x8547,0x70}, + {0x8548,0x03}, + {0x8549,0x02}, + {0x854a,0x05}, + {0x854b,0xe4}, + {0x854c,0x24}, + {0x854d,0x10}, + {0x854e,0x60}, + {0x854f,0x03}, + {0x8550,0x02}, + {0x8551,0x06}, + {0x8552,0xdf}, + {0x8553,0xe4}, + {0x8554,0xf5}, + {0x8555,0x0a}, + {0x8556,0x12}, + {0x8557,0x12}, + {0x8558,0x9c}, + {0x8559,0x02}, + {0x855a,0x06}, + {0x855b,0xc8}, + {0x855c,0x75}, + {0x855d,0x0a}, + {0x855e,0x01}, + {0x855f,0x12}, + {0x8560,0x06}, + {0x8561,0xe0}, + {0x8562,0xc2}, + {0x8563,0x3c}, + {0x8564,0xd2}, + {0x8565,0x3b}, + {0x8566,0x02}, + {0x8567,0x06}, + {0x8568,0xd9}, + {0x8569,0x75}, + {0x856a,0x0a}, + {0x856b,0x02}, + {0x856c,0x12}, + {0x856d,0x06}, + {0x856e,0xe0}, + {0x856f,0xd2}, + {0x8570,0x3c}, + {0x8571,0xc2}, + {0x8572,0x3b}, + {0x8573,0x02}, + {0x8574,0x06}, + {0x8575,0xd9}, + {0x8576,0x30}, + {0x8577,0x38}, + {0x8578,0x0c}, + {0x8579,0x20}, + {0x857a,0x3c}, + {0x857b,0x03}, + {0x857c,0x30}, + {0x857d,0x3b}, + {0x857e,0x06}, + {0x857f,0xe4}, + {0x8580,0xf5}, + {0x8581,0x0a}, + {0x8582,0x12}, + {0x8583,0x14}, + {0x8584,0x78}, + {0x8585,0xd2}, + {0x8586,0x18}, + {0x8587,0xc2}, + {0x8588,0x19}, + {0x8589,0x22}, + {0x858a,0x30}, + {0x858b,0x38}, + {0x858c,0x09}, + {0x858d,0x20}, + {0x858e,0x3c}, + {0x858f,0x03}, + {0x8590,0x30}, + {0x8591,0x3b}, + {0x8592,0x03}, + {0x8593,0x12}, + {0x8594,0x06}, + {0x8595,0xf1}, + {0x8596,0xd2}, + {0x8597,0x18}, + {0x8598,0xd2}, + {0x8599,0x19}, + {0x859a,0x22}, + {0x859b,0x30}, + {0x859c,0x38}, + {0x859d,0x0c}, + {0x859e,0x20}, + {0x859f,0x3c}, + {0x85a0,0x03}, + {0x85a1,0x30}, + {0x85a2,0x3b}, + {0x85a3,0x06}, + {0x85a4,0x75}, + {0x85a5,0x0a}, + {0x85a6,0x02}, + {0x85a7,0x12}, + {0x85a8,0x14}, + {0x85a9,0x78}, + {0x85aa,0xc2}, + {0x85ab,0x18}, + {0x85ac,0xd2}, + {0x85ad,0x19}, + {0x85ae,0x22}, + {0x85af,0x20}, + {0x85b0,0x3c}, + {0x85b1,0x06}, + {0x85b2,0x20}, + {0x85b3,0x3b}, + {0x85b4,0x03}, + {0x85b5,0x02}, + {0x85b6,0x06}, + {0x85b7,0xdf}, + {0x85b8,0xe5}, + {0x85b9,0x79}, + {0x85ba,0xd3}, + {0x85bb,0x94}, + {0x85bc,0x03}, + {0x85bd,0x40}, + {0x85be,0x04}, + {0x85bf,0x7f}, + {0x85c0,0x00}, + {0x85c1,0x80}, + {0x85c2,0x04}, + {0x85c3,0xe5}, + {0x85c4,0x79}, + {0x85c5,0x04}, + {0x85c6,0xff}, + {0x85c7,0x8f}, + {0x85c8,0x79}, + {0x85c9,0x30}, + {0x85ca,0x18}, + {0x85cb,0x06}, + {0x85cc,0x30}, + {0x85cd,0x19}, + {0x85ce,0x03}, + {0x85cf,0x12}, + {0x85d0,0x06}, + {0x85d1,0xf1}, + {0x85d2,0x30}, + {0x85d3,0x18}, + {0x85d4,0x03}, + {0x85d5,0x02}, + {0x85d6,0x06}, + {0x85d7,0xdf}, + {0x85d8,0x20}, + {0x85d9,0x19}, + {0x85da,0x03}, + {0x85db,0x02}, + {0x85dc,0x06}, + {0x85dd,0xdf}, + {0x85de,0x75}, + {0x85df,0x0a}, + {0x85e0,0x02}, + {0x85e1,0x02}, + {0x85e2,0x14}, + {0x85e3,0x78}, + {0x85e4,0xe5}, + {0x85e5,0x68}, + {0x85e6,0xd3}, + {0x85e7,0x94}, + {0x85e8,0x38}, + {0x85e9,0x40}, + {0x85ea,0x04}, + {0x85eb,0x7f}, + {0x85ec,0x34}, + {0x85ed,0x80}, + {0x85ee,0x02}, + {0x85ef,0xaf}, + {0x85f0,0x68}, + {0x85f1,0x8f}, + {0x85f2,0x68}, + {0x85f3,0xe5}, + {0x85f4,0x68}, + {0x85f5,0xc3}, + {0x85f6,0x94}, + {0x85f7,0x08}, + {0x85f8,0x50}, + {0x85f9,0x04}, + {0x85fa,0x7f}, + {0x85fb,0x08}, + {0x85fc,0x80}, + {0x85fd,0x02}, + {0x85fe,0xaf}, + {0x85ff,0x68}, + {0x8600,0x8f}, + {0x8601,0x68}, + {0x8602,0xe5}, + {0x8603,0x69}, + {0x8604,0xd3}, + {0x8605,0x94}, + {0x8606,0x2a}, + {0x8607,0x40}, + {0x8608,0x04}, + {0x8609,0x7f}, + {0x860a,0x2a}, + {0x860b,0x80}, + {0x860c,0x02}, + {0x860d,0xaf}, + {0x860e,0x69}, + {0x860f,0x8f}, + {0x8610,0x69}, + {0x8611,0xe5}, + {0x8612,0x69}, + {0x8613,0xc3}, + {0x8614,0x94}, + {0x8615,0x06}, + {0x8616,0x50}, + {0x8617,0x04}, + {0x8618,0x7f}, + {0x8619,0x06}, + {0x861a,0x80}, + {0x861b,0x02}, + {0x861c,0xaf}, + {0x861d,0x69}, + {0x861e,0x8f}, + {0x861f,0x69}, + {0x8620,0xaf}, + {0x8621,0x68}, + {0x8622,0xef}, + {0x8623,0x24}, + {0x8624,0xf8}, + {0x8625,0xff}, + {0x8626,0xe4}, + {0x8627,0x34}, + {0x8628,0xff}, + {0x8629,0xfe}, + {0x862a,0xe4}, + {0x862b,0x8f}, + {0x862c,0x3f}, + {0x862d,0x8e}, + {0x862e,0x3e}, + {0x862f,0xf5}, + {0x8630,0x3d}, + {0x8631,0xf5}, + {0x8632,0x3c}, + {0x8633,0xac}, + {0x8634,0x3c}, + {0x8635,0x12}, + {0x8636,0x01}, + {0x8637,0xb9}, + {0x8638,0xaf}, + {0x8639,0x69}, + {0x863a,0xef}, + {0x863b,0x24}, + {0x863c,0xfa}, + {0x863d,0xff}, + {0x863e,0xe4}, + {0x863f,0x34}, + {0x8640,0xff}, + {0x8641,0x12}, + {0x8642,0x01}, + {0x8643,0x9c}, + {0x8644,0xaf}, + {0x8645,0x68}, + {0x8646,0xef}, + {0x8647,0x24}, + {0x8648,0x08}, + {0x8649,0xff}, + {0x864a,0xe4}, + {0x864b,0x33}, + {0x864c,0x12}, + {0x864d,0x01}, + {0x864e,0x9c}, + {0x864f,0xaf}, + {0x8650,0x69}, + {0x8651,0xef}, + {0x8652,0x24}, + {0x8653,0x06}, + {0x8654,0xff}, + {0x8655,0xe4}, + {0x8656,0x33}, + {0x8657,0xfe}, + {0x8658,0xe4}, + {0x8659,0xfc}, + {0x865a,0xfd}, + {0x865b,0xe5}, + {0x865c,0x3f}, + {0x865d,0x2f}, + {0x865e,0xf5}, + {0x865f,0x3f}, + {0x8660,0xe5}, + {0x8661,0x3e}, + {0x8662,0x3e}, + {0x8663,0xf5}, + {0x8664,0x3e}, + {0x8665,0xed}, + {0x8666,0x35}, + {0x8667,0x3d}, + {0x8668,0xf5}, + {0x8669,0x3d}, + {0x866a,0xec}, + {0x866b,0x35}, + {0x866c,0x3c}, + {0x866d,0xf5}, + {0x866e,0x3c}, + {0x866f,0xe4}, + {0x8670,0x25}, + {0x8671,0x3f}, + {0x8672,0xf5}, + {0x8673,0x37}, + {0x8674,0xe4}, + {0x8675,0x35}, + {0x8676,0x3e}, + {0x8677,0xf5}, + {0x8678,0x36}, + {0x8679,0xe4}, + {0x867a,0x35}, + {0x867b,0x3d}, + {0x867c,0xf5}, + {0x867d,0x35}, + {0x867e,0xe5}, + {0x867f,0x3c}, + {0x8680,0x34}, + {0x8681,0x08}, + {0x8682,0xf5}, + {0x8683,0x34}, + {0x8684,0xe4}, + {0x8685,0x25}, + {0x8686,0x3f}, + {0x8687,0xf5}, + {0x8688,0x3b}, + {0x8689,0xe4}, + {0x868a,0x35}, + {0x868b,0x3e}, + {0x868c,0xf5}, + {0x868d,0x3a}, + {0x868e,0xe5}, + {0x868f,0x3d}, + {0x8690,0x34}, + {0x8691,0x06}, + {0x8692,0xf5}, + {0x8693,0x39}, + {0x8694,0xe4}, + {0x8695,0x35}, + {0x8696,0x3c}, + {0x8697,0xf5}, + {0x8698,0x38}, + {0x8699,0xe5}, + {0x869a,0x3f}, + {0x869b,0x24}, + {0x869c,0xfa}, + {0x869d,0xf5}, + {0x869e,0x43}, + {0x869f,0xe5}, + {0x86a0,0x3e}, + {0x86a1,0x34}, + {0x86a2,0xff}, + {0x86a3,0xf5}, + {0x86a4,0x42}, + {0x86a5,0xe5}, + {0x86a6,0x3d}, + {0x86a7,0x34}, + {0x86a8,0xff}, + {0x86a9,0xf5}, + {0x86aa,0x41}, + {0x86ab,0xe5}, + {0x86ac,0x3c}, + {0x86ad,0x34}, + {0x86ae,0xff}, + {0x86af,0xf5}, + {0x86b0,0x40}, + {0x86b1,0xe4}, + {0x86b2,0x25}, + {0x86b3,0x3f}, + {0x86b4,0xf5}, + {0x86b5,0x47}, + {0x86b6,0xe5}, + {0x86b7,0x3e}, + {0x86b8,0x34}, + {0x86b9,0xf8}, + {0x86ba,0xf5}, + {0x86bb,0x46}, + {0x86bc,0xe5}, + {0x86bd,0x3d}, + {0x86be,0x34}, + {0x86bf,0xff}, + {0x86c0,0xf5}, + {0x86c1,0x45}, + {0x86c2,0xe5}, + {0x86c3,0x3c}, + {0x86c4,0x34}, + {0x86c5,0xff}, + {0x86c6,0xf5}, + {0x86c7,0x44}, + {0x86c8,0x75}, + {0x86c9,0x79}, + {0x86ca,0x02}, + {0x86cb,0x75}, + {0x86cc,0x0a}, + {0x86cd,0x01}, + {0x86ce,0x12}, + {0x86cf,0x14}, + {0x86d0,0x78}, + {0x86d1,0xd2}, + {0x86d2,0x18}, + {0x86d3,0xd2}, + {0x86d4,0x19}, + {0x86d5,0xc2}, + {0x86d6,0x3c}, + {0x86d7,0xc2}, + {0x86d8,0x3b}, + {0x86d9,0xd2}, + {0x86da,0x1a}, + {0x86db,0xd2}, + {0x86dc,0x38}, + {0x86dd,0xd2}, + {0x86de,0x30}, + {0x86df,0x22}, + {0x86e0,0x12}, + {0x86e1,0x12}, + {0x86e2,0x9c}, + {0x86e3,0x75}, + {0x86e4,0x79}, + {0x86e5,0x02}, + {0x86e6,0xe4}, + {0x86e7,0xf5}, + {0x86e8,0x0a}, + {0x86e9,0x12}, + {0x86ea,0x14}, + {0x86eb,0x78}, + {0x86ec,0xd2}, + {0x86ed,0x18}, + {0x86ee,0xc2}, + {0x86ef,0x19}, + {0x86f0,0x22}, + {0x86f1,0x75}, + {0x86f2,0x0a}, + {0x86f3,0x01}, + {0x86f4,0x12}, + {0x86f5,0x14}, + {0x86f6,0x78}, + {0x86f7,0x22}, + {0x86f8,0x90}, + {0x86f9,0x38}, + {0x86fa,0x04}, + {0x86fb,0xe0}, + {0x86fc,0xfe}, + {0x86fd,0xa3}, + {0x86fe,0xe0}, + {0x86ff,0xfd}, + {0x8700,0xed}, + {0x8701,0xff}, + {0x8702,0xee}, + {0x8703,0x54}, + {0x8704,0x0f}, + {0x8705,0xf5}, + {0x8706,0x0e}, + {0x8707,0x8f}, + {0x8708,0x0f}, + {0x8709,0xa3}, + {0x870a,0xe0}, + {0x870b,0xfe}, + {0x870c,0xa3}, + {0x870d,0xe0}, + {0x870e,0xfd}, + {0x870f,0xed}, + {0x8710,0xff}, + {0x8711,0xee}, + {0x8712,0x54}, + {0x8713,0x07}, + {0x8714,0xf5}, + {0x8715,0x10}, + {0x8716,0x8f}, + {0x8717,0x11}, + {0x8718,0xe5}, + {0x8719,0x0e}, + {0x871a,0xc4}, + {0x871b,0xf8}, + {0x871c,0x54}, + {0x871d,0xf0}, + {0x871e,0xc8}, + {0x871f,0x68}, + {0x8720,0xf5}, + {0x8721,0x0e}, + {0x8722,0xe5}, + {0x8723,0x0f}, + {0x8724,0xc4}, + {0x8725,0x54}, + {0x8726,0x0f}, + {0x8727,0x48}, + {0x8728,0xf5}, + {0x8729,0x0f}, + {0x872a,0xe5}, + {0x872b,0x10}, + {0x872c,0xc4}, + {0x872d,0xf8}, + {0x872e,0x54}, + {0x872f,0xf0}, + {0x8730,0xc8}, + {0x8731,0x68}, + {0x8732,0xf5}, + {0x8733,0x10}, + {0x8734,0xe5}, + {0x8735,0x11}, + {0x8736,0xc4}, + {0x8737,0x54}, + {0x8738,0x0f}, + {0x8739,0x48}, + {0x873a,0xf5}, + {0x873b,0x11}, + {0x873c,0xe4}, + {0x873d,0xf5}, + {0x873e,0x17}, + {0x873f,0x75}, + {0x8740,0x16}, + {0x8741,0x04}, + {0x8742,0x12}, + {0x8743,0x02}, + {0x8744,0x60}, + {0x8745,0x24}, + {0x8746,0x34}, + {0x8747,0xf8}, + {0x8748,0xe6}, + {0x8749,0xf5}, + {0x874a,0x12}, + {0x874b,0x12}, + {0x874c,0x02}, + {0x874d,0x60}, + {0x874e,0x24}, + {0x874f,0x35}, + {0x8750,0xf8}, + {0x8751,0xe6}, + {0x8752,0xf5}, + {0x8753,0x14}, + {0x8754,0x12}, + {0x8755,0x02}, + {0x8756,0x60}, + {0x8757,0x24}, + {0x8758,0x36}, + {0x8759,0xf8}, + {0x875a,0xe6}, + {0x875b,0xf5}, + {0x875c,0x13}, + {0x875d,0x12}, + {0x875e,0x02}, + {0x875f,0x60}, + {0x8760,0x24}, + {0x8761,0x37}, + {0x8762,0xf8}, + {0x8763,0xe6}, + {0x8764,0xf5}, + {0x8765,0x15}, + {0x8766,0x12}, + {0x8767,0x02}, + {0x8768,0x73}, + {0x8769,0xaf}, + {0x876a,0x12}, + {0x876b,0x12}, + {0x876c,0x01}, + {0x876d,0x42}, + {0x876e,0x8f}, + {0x876f,0x12}, + {0x8770,0x12}, + {0x8771,0x02}, + {0x8772,0x73}, + {0x8773,0xaf}, + {0x8774,0x13}, + {0x8775,0x12}, + {0x8776,0x01}, + {0x8777,0x42}, + {0x8778,0x8f}, + {0x8779,0x13}, + {0x877a,0x12}, + {0x877b,0x02}, + {0x877c,0x1b}, + {0x877d,0xaf}, + {0x877e,0x14}, + {0x877f,0xfc}, + {0x8780,0xfd}, + {0x8781,0xfe}, + {0x8782,0x12}, + {0x8783,0x08}, + {0x8784,0x98}, + {0x8785,0x12}, + {0x8786,0x01}, + {0x8787,0x61}, + {0x8788,0x7b}, + {0x8789,0x30}, + {0x878a,0x12}, + {0x878b,0x01}, + {0x878c,0x5a}, + {0x878d,0x8f}, + {0x878e,0x14}, + {0x878f,0x12}, + {0x8790,0x02}, + {0x8791,0x1b}, + {0x8792,0xaf}, + {0x8793,0x15}, + {0x8794,0xfc}, + {0x8795,0xfd}, + {0x8796,0xfe}, + {0x8797,0x12}, + {0x8798,0x08}, + {0x8799,0x98}, + {0x879a,0x12}, + {0x879b,0x01}, + {0x879c,0x61}, + {0x879d,0xe4}, + {0x879e,0x7b}, + {0x879f,0x30}, + {0x87a0,0x12}, + {0x87a1,0x01}, + {0x87a2,0x5b}, + {0x87a3,0x8f}, + {0x87a4,0x15}, + {0x87a5,0xc3}, + {0x87a6,0xe5}, + {0x87a7,0x13}, + {0x87a8,0x95}, + {0x87a9,0x12}, + {0x87aa,0xff}, + {0x87ab,0x0f}, + {0x87ac,0xef}, + {0x87ad,0xc3}, + {0x87ae,0x13}, + {0x87af,0xff}, + {0x87b0,0xc3}, + {0x87b1,0x94}, + {0x87b2,0x04}, + {0x87b3,0x50}, + {0x87b4,0x27}, + {0x87b5,0xe5}, + {0x87b6,0x12}, + {0x87b7,0x9f}, + {0x87b8,0x40}, + {0x87b9,0x06}, + {0x87ba,0xe5}, + {0x87bb,0x12}, + {0x87bc,0x9f}, + {0x87bd,0xfe}, + {0x87be,0x80}, + {0x87bf,0x02}, + {0x87c0,0x7e}, + {0x87c1,0x00}, + {0x87c2,0x8e}, + {0x87c3,0x12}, + {0x87c4,0xef}, + {0x87c5,0xfd}, + {0x87c6,0xe5}, + {0x87c7,0x13}, + {0x87c8,0x2d}, + {0x87c9,0xfd}, + {0x87ca,0xe4}, + {0x87cb,0x33}, + {0x87cc,0xfc}, + {0x87cd,0xc3}, + {0x87ce,0xed}, + {0x87cf,0x95}, + {0x87d0,0x0f}, + {0x87d1,0xec}, + {0x87d2,0x95}, + {0x87d3,0x0e}, + {0x87d4,0x50}, + {0x87d5,0x02}, + {0x87d6,0x80}, + {0x87d7,0x02}, + {0x87d8,0xad}, + {0x87d9,0x0f}, + {0x87da,0x8d}, + {0x87db,0x13}, + {0x87dc,0xc3}, + {0x87dd,0xe5}, + {0x87de,0x15}, + {0x87df,0x95}, + {0x87e0,0x14}, + {0x87e1,0xff}, + {0x87e2,0xc3}, + {0x87e3,0x94}, + {0x87e4,0x04}, + {0x87e5,0x50}, + {0x87e6,0x29}, + {0x87e7,0xe5}, + {0x87e8,0x14}, + {0x87e9,0x9f}, + {0x87ea,0x40}, + {0x87eb,0x06}, + {0x87ec,0xe5}, + {0x87ed,0x14}, + {0x87ee,0x9f}, + {0x87ef,0xfe}, + {0x87f0,0x80}, + {0x87f1,0x02}, + {0x87f2,0x7e}, + {0x87f3,0x00}, + {0x87f4,0x8e}, + {0x87f5,0x14}, + {0x87f6,0xef}, + {0x87f7,0xfd}, + {0x87f8,0xe5}, + {0x87f9,0x15}, + {0x87fa,0x2d}, + {0x87fb,0xfd}, + {0x87fc,0xe4}, + {0x87fd,0x33}, + {0x87fe,0xfc}, + {0x87ff,0xc3}, + {0x8800,0xed}, + {0x8801,0x95}, + {0x8802,0x11}, + {0x8803,0xec}, + {0x8804,0x95}, + {0x8805,0x10}, + {0x8806,0x50}, + {0x8807,0x04}, + {0x8808,0xaf}, + {0x8809,0x05}, + {0x880a,0x80}, + {0x880b,0x02}, + {0x880c,0xaf}, + {0x880d,0x11}, + {0x880e,0x8f}, + {0x880f,0x15}, + {0x8810,0xe5}, + {0x8811,0x15}, + {0x8812,0xd3}, + {0x8813,0x95}, + {0x8814,0x17}, + {0x8815,0x40}, + {0x8816,0x04}, + {0x8817,0xaf}, + {0x8818,0x15}, + {0x8819,0x80}, + {0x881a,0x02}, + {0x881b,0xaf}, + {0x881c,0x17}, + {0x881d,0x8f}, + {0x881e,0x17}, + {0x881f,0xd3}, + {0x8820,0xe5}, + {0x8821,0x16}, + {0x8822,0x64}, + {0x8823,0x80}, + {0x8824,0x94}, + {0x8825,0x80}, + {0x8826,0x40}, + {0x8827,0x04}, + {0x8828,0xaf}, + {0x8829,0x15}, + {0x882a,0x80}, + {0x882b,0x02}, + {0x882c,0xaf}, + {0x882d,0x17}, + {0x882e,0x8f}, + {0x882f,0x15}, + {0x8830,0xe5}, + {0x8831,0x16}, + {0x8832,0xfd}, + {0x8833,0x33}, + {0x8834,0x95}, + {0x8835,0xe0}, + {0x8836,0xfc}, + {0x8837,0xed}, + {0x8838,0xae}, + {0x8839,0x04}, + {0x883a,0x78}, + {0x883b,0x02}, + {0x883c,0xc3}, + {0x883d,0x33}, + {0x883e,0xce}, + {0x883f,0x33}, + {0x8840,0xce}, + {0x8841,0xd8}, + {0x8842,0xf9}, + {0x8843,0xff}, + {0x8844,0x24}, + {0x8845,0x01}, + {0x8846,0xfb}, + {0x8847,0xee}, + {0x8848,0x34}, + {0x8849,0x60}, + {0x884a,0x8b}, + {0x884b,0x82}, + {0x884c,0xf5}, + {0x884d,0x83}, + {0x884e,0xe5}, + {0x884f,0x12}, + {0x8850,0xf0}, + {0x8851,0xef}, + {0x8852,0x24}, + {0x8853,0x02}, + {0x8854,0xff}, + {0x8855,0xee}, + {0x8856,0x34}, + {0x8857,0x60}, + {0x8858,0x8f}, + {0x8859,0x82}, + {0x885a,0xf5}, + {0x885b,0x83}, + {0x885c,0xe5}, + {0x885d,0x14}, + {0x885e,0xf0}, + {0x885f,0xed}, + {0x8860,0xae}, + {0x8861,0x04}, + {0x8862,0x78}, + {0x8863,0x02}, + {0x8864,0xc3}, + {0x8865,0x33}, + {0x8866,0xce}, + {0x8867,0x33}, + {0x8868,0xce}, + {0x8869,0xd8}, + {0x886a,0xf9}, + {0x886b,0xff}, + {0x886c,0x24}, + {0x886d,0x03}, + {0x886e,0xfd}, + {0x886f,0xee}, + {0x8870,0x34}, + {0x8871,0x60}, + {0x8872,0x8d}, + {0x8873,0x82}, + {0x8874,0xf5}, + {0x8875,0x83}, + {0x8876,0xe5}, + {0x8877,0x13}, + {0x8878,0xf0}, + {0x8879,0xef}, + {0x887a,0x24}, + {0x887b,0x04}, + {0x887c,0xff}, + {0x887d,0xee}, + {0x887e,0x34}, + {0x887f,0x60}, + {0x8880,0x8f}, + {0x8881,0x82}, + {0x8882,0xf5}, + {0x8883,0x83}, + {0x8884,0xe5}, + {0x8885,0x15}, + {0x8886,0xf0}, + {0x8887,0x15}, + {0x8888,0x16}, + {0x8889,0xc3}, + {0x888a,0xe5}, + {0x888b,0x16}, + {0x888c,0x64}, + {0x888d,0x80}, + {0x888e,0x94}, + {0x888f,0x80}, + {0x8890,0x40}, + {0x8891,0x03}, + {0x8892,0x02}, + {0x8893,0x07}, + {0x8894,0x42}, + {0x8895,0xc2}, + {0x8896,0x30}, + {0x8897,0x22}, + {0x8898,0xe8}, + {0x8899,0x8f}, + {0x889a,0xf0}, + {0x889b,0xa4}, + {0x889c,0xcc}, + {0x889d,0x8b}, + {0x889e,0xf0}, + {0x889f,0xa4}, + {0x88a0,0x2c}, + {0x88a1,0xfc}, + {0x88a2,0xe9}, + {0x88a3,0x8e}, + {0x88a4,0xf0}, + {0x88a5,0xa4}, + {0x88a6,0x2c}, + {0x88a7,0xfc}, + {0x88a8,0x8a}, + {0x88a9,0xf0}, + {0x88aa,0xed}, + {0x88ab,0xa4}, + {0x88ac,0x2c}, + {0x88ad,0xfc}, + {0x88ae,0xea}, + {0x88af,0x8e}, + {0x88b0,0xf0}, + {0x88b1,0xa4}, + {0x88b2,0xcd}, + {0x88b3,0xa8}, + {0x88b4,0xf0}, + {0x88b5,0x8b}, + {0x88b6,0xf0}, + {0x88b7,0xa4}, + {0x88b8,0x2d}, + {0x88b9,0xcc}, + {0x88ba,0x38}, + {0x88bb,0x25}, + {0x88bc,0xf0}, + {0x88bd,0xfd}, + {0x88be,0xe9}, + {0x88bf,0x8f}, + {0x88c0,0xf0}, + {0x88c1,0xa4}, + {0x88c2,0x2c}, + {0x88c3,0xcd}, + {0x88c4,0x35}, + {0x88c5,0xf0}, + {0x88c6,0xfc}, + {0x88c7,0xeb}, + {0x88c8,0x8e}, + {0x88c9,0xf0}, + {0x88ca,0xa4}, + {0x88cb,0xfe}, + {0x88cc,0xa9}, + {0x88cd,0xf0}, + {0x88ce,0xeb}, + {0x88cf,0x8f}, + {0x88d0,0xf0}, + {0x88d1,0xa4}, + {0x88d2,0xcf}, + {0x88d3,0xc5}, + {0x88d4,0xf0}, + {0x88d5,0x2e}, + {0x88d6,0xcd}, + {0x88d7,0x39}, + {0x88d8,0xfe}, + {0x88d9,0xe4}, + {0x88da,0x3c}, + {0x88db,0xfc}, + {0x88dc,0xea}, + {0x88dd,0xa4}, + {0x88de,0x2d}, + {0x88df,0xce}, + {0x88e0,0x35}, + {0x88e1,0xf0}, + {0x88e2,0xfd}, + {0x88e3,0xe4}, + {0x88e4,0x3c}, + {0x88e5,0xfc}, + {0x88e6,0x22}, + {0x88e7,0x75}, + {0x88e8,0xf0}, + {0x88e9,0x08}, + {0x88ea,0x75}, + {0x88eb,0x82}, + {0x88ec,0x00}, + {0x88ed,0xef}, + {0x88ee,0x2f}, + {0x88ef,0xff}, + {0x88f0,0xee}, + {0x88f1,0x33}, + {0x88f2,0xfe}, + {0x88f3,0xcd}, + {0x88f4,0x33}, + {0x88f5,0xcd}, + {0x88f6,0xcc}, + {0x88f7,0x33}, + {0x88f8,0xcc}, + {0x88f9,0xc5}, + {0x88fa,0x82}, + {0x88fb,0x33}, + {0x88fc,0xc5}, + {0x88fd,0x82}, + {0x88fe,0x9b}, + {0x88ff,0xed}, + {0x8900,0x9a}, + {0x8901,0xec}, + {0x8902,0x99}, + {0x8903,0xe5}, + {0x8904,0x82}, + {0x8905,0x98}, + {0x8906,0x40}, + {0x8907,0x0c}, + {0x8908,0xf5}, + {0x8909,0x82}, + {0x890a,0xee}, + {0x890b,0x9b}, + {0x890c,0xfe}, + {0x890d,0xed}, + {0x890e,0x9a}, + {0x890f,0xfd}, + {0x8910,0xec}, + {0x8911,0x99}, + {0x8912,0xfc}, + {0x8913,0x0f}, + {0x8914,0xd5}, + {0x8915,0xf0}, + {0x8916,0xd6}, + {0x8917,0xe4}, + {0x8918,0xce}, + {0x8919,0xfb}, + {0x891a,0xe4}, + {0x891b,0xcd}, + {0x891c,0xfa}, + {0x891d,0xe4}, + {0x891e,0xcc}, + {0x891f,0xf9}, + {0x8920,0xa8}, + {0x8921,0x82}, + {0x8922,0x22}, + {0x8923,0xb8}, + {0x8924,0x00}, + {0x8925,0xc1}, + {0x8926,0xb9}, + {0x8927,0x00}, + {0x8928,0x59}, + {0x8929,0xba}, + {0x892a,0x00}, + {0x892b,0x2d}, + {0x892c,0xec}, + {0x892d,0x8b}, + {0x892e,0xf0}, + {0x892f,0x84}, + {0x8930,0xcf}, + {0x8931,0xce}, + {0x8932,0xcd}, + {0x8933,0xfc}, + {0x8934,0xe5}, + {0x8935,0xf0}, + {0x8936,0xcb}, + {0x8937,0xf9}, + {0x8938,0x78}, + {0x8939,0x18}, + {0x893a,0xef}, + {0x893b,0x2f}, + {0x893c,0xff}, + {0x893d,0xee}, + {0x893e,0x33}, + {0x893f,0xfe}, + {0x8940,0xed}, + {0x8941,0x33}, + {0x8942,0xfd}, + {0x8943,0xec}, + {0x8944,0x33}, + {0x8945,0xfc}, + {0x8946,0xeb}, + {0x8947,0x33}, + {0x8948,0xfb}, + {0x8949,0x10}, + {0x894a,0xd7}, + {0x894b,0x03}, + {0x894c,0x99}, + {0x894d,0x40}, + {0x894e,0x04}, + {0x894f,0xeb}, + {0x8950,0x99}, + {0x8951,0xfb}, + {0x8952,0x0f}, + {0x8953,0xd8}, + {0x8954,0xe5}, + {0x8955,0xe4}, + {0x8956,0xf9}, + {0x8957,0xfa}, + {0x8958,0x22}, + {0x8959,0x78}, + {0x895a,0x18}, + {0x895b,0xef}, + {0x895c,0x2f}, + {0x895d,0xff}, + {0x895e,0xee}, + {0x895f,0x33}, + {0x8960,0xfe}, + {0x8961,0xed}, + {0x8962,0x33}, + {0x8963,0xfd}, + {0x8964,0xec}, + {0x8965,0x33}, + {0x8966,0xfc}, + {0x8967,0xc9}, + {0x8968,0x33}, + {0x8969,0xc9}, + {0x896a,0x10}, + {0x896b,0xd7}, + {0x896c,0x05}, + {0x896d,0x9b}, + {0x896e,0xe9}, + {0x896f,0x9a}, + {0x8970,0x40}, + {0x8971,0x07}, + {0x8972,0xec}, + {0x8973,0x9b}, + {0x8974,0xfc}, + {0x8975,0xe9}, + {0x8976,0x9a}, + {0x8977,0xf9}, + {0x8978,0x0f}, + {0x8979,0xd8}, + {0x897a,0xe0}, + {0x897b,0xe4}, + {0x897c,0xc9}, + {0x897d,0xfa}, + {0x897e,0xe4}, + {0x897f,0xcc}, + {0x8980,0xfb}, + {0x8981,0x22}, + {0x8982,0x75}, + {0x8983,0xf0}, + {0x8984,0x10}, + {0x8985,0xef}, + {0x8986,0x2f}, + {0x8987,0xff}, + {0x8988,0xee}, + {0x8989,0x33}, + {0x898a,0xfe}, + {0x898b,0xed}, + {0x898c,0x33}, + {0x898d,0xfd}, + {0x898e,0xcc}, + {0x898f,0x33}, + {0x8990,0xcc}, + {0x8991,0xc8}, + {0x8992,0x33}, + {0x8993,0xc8}, + {0x8994,0x10}, + {0x8995,0xd7}, + {0x8996,0x07}, + {0x8997,0x9b}, + {0x8998,0xec}, + {0x8999,0x9a}, + {0x899a,0xe8}, + {0x899b,0x99}, + {0x899c,0x40}, + {0x899d,0x0a}, + {0x899e,0xed}, + {0x899f,0x9b}, + {0x89a0,0xfd}, + {0x89a1,0xec}, + {0x89a2,0x9a}, + {0x89a3,0xfc}, + {0x89a4,0xe8}, + {0x89a5,0x99}, + {0x89a6,0xf8}, + {0x89a7,0x0f}, + {0x89a8,0xd5}, + {0x89a9,0xf0}, + {0x89aa,0xda}, + {0x89ab,0xe4}, + {0x89ac,0xcd}, + {0x89ad,0xfb}, + {0x89ae,0xe4}, + {0x89af,0xcc}, + {0x89b0,0xfa}, + {0x89b1,0xe4}, + {0x89b2,0xc8}, + {0x89b3,0xf9}, + {0x89b4,0x22}, + {0x89b5,0xe8}, + {0x89b6,0x60}, + {0x89b7,0x0f}, + {0x89b8,0xec}, + {0x89b9,0xc3}, + {0x89ba,0x13}, + {0x89bb,0xfc}, + {0x89bc,0xed}, + {0x89bd,0x13}, + {0x89be,0xfd}, + {0x89bf,0xee}, + {0x89c0,0x13}, + {0x89c1,0xfe}, + {0x89c2,0xef}, + {0x89c3,0x13}, + {0x89c4,0xff}, + {0x89c5,0xd8}, + {0x89c6,0xf1}, + {0x89c7,0x22}, + {0x89c8,0xe8}, + {0x89c9,0x60}, + {0x89ca,0x0f}, + {0x89cb,0xef}, + {0x89cc,0xc3}, + {0x89cd,0x33}, + {0x89ce,0xff}, + {0x89cf,0xee}, + {0x89d0,0x33}, + {0x89d1,0xfe}, + {0x89d2,0xed}, + {0x89d3,0x33}, + {0x89d4,0xfd}, + {0x89d5,0xec}, + {0x89d6,0x33}, + {0x89d7,0xfc}, + {0x89d8,0xd8}, + {0x89d9,0xf1}, + {0x89da,0x22}, + {0x89db,0xe4}, + {0x89dc,0x93}, + {0x89dd,0xfc}, + {0x89de,0x74}, + {0x89df,0x01}, + {0x89e0,0x93}, + {0x89e1,0xfd}, + {0x89e2,0x74}, + {0x89e3,0x02}, + {0x89e4,0x93}, + {0x89e5,0xfe}, + {0x89e6,0x74}, + {0x89e7,0x03}, + {0x89e8,0x93}, + {0x89e9,0xff}, + {0x89ea,0x22}, + {0x89eb,0xa4}, + {0x89ec,0x25}, + {0x89ed,0x82}, + {0x89ee,0xf5}, + {0x89ef,0x82}, + {0x89f0,0xe5}, + {0x89f1,0xf0}, + {0x89f2,0x35}, + {0x89f3,0x83}, + {0x89f4,0xf5}, + {0x89f5,0x83}, + {0x89f6,0x22}, + {0x89f7,0xd0}, + {0x89f8,0x83}, + {0x89f9,0xd0}, + {0x89fa,0x82}, + {0x89fb,0xf8}, + {0x89fc,0xe4}, + {0x89fd,0x93}, + {0x89fe,0x70}, + {0x89ff,0x12}, + {0x8a00,0x74}, + {0x8a01,0x01}, + {0x8a02,0x93}, + {0x8a03,0x70}, + {0x8a04,0x0d}, + {0x8a05,0xa3}, + {0x8a06,0xa3}, + {0x8a07,0x93}, + {0x8a08,0xf8}, + {0x8a09,0x74}, + {0x8a0a,0x01}, + {0x8a0b,0x93}, + {0x8a0c,0xf5}, + {0x8a0d,0x82}, + {0x8a0e,0x88}, + {0x8a0f,0x83}, + {0x8a10,0xe4}, + {0x8a11,0x73}, + {0x8a12,0x74}, + {0x8a13,0x02}, + {0x8a14,0x93}, + {0x8a15,0x68}, + {0x8a16,0x60}, + {0x8a17,0xef}, + {0x8a18,0xa3}, + {0x8a19,0xa3}, + {0x8a1a,0xa3}, + {0x8a1b,0x80}, + {0x8a1c,0xdf}, + {0x8a1d,0x75}, + {0x8a1e,0x0f}, + {0x8a1f,0x0a}, + {0x8a20,0xa2}, + {0x8a21,0xaf}, + {0x8a22,0x92}, + {0x8a23,0x32}, + {0x8a24,0xc2}, + {0x8a25,0xaf}, + {0x8a26,0xc2}, + {0x8a27,0x33}, + {0x8a28,0x12}, + {0x8a29,0x01}, + {0x8a2a,0x6a}, + {0x8a2b,0x12}, + {0x8a2c,0x02}, + {0x8a2d,0x12}, + {0x8a2e,0x12}, + {0x8a2f,0x01}, + {0x8a30,0x6a}, + {0x8a31,0x75}, + {0x8a32,0x51}, + {0x8a33,0x05}, + {0x8a34,0xaf}, + {0x8a35,0x51}, + {0x8a36,0x15}, + {0x8a37,0x51}, + {0x8a38,0xef}, + {0x8a39,0x70}, + {0x8a3a,0xf9}, + {0x8a3b,0xd2}, + {0x8a3c,0x28}, + {0x8a3d,0x12}, + {0x8a3e,0x01}, + {0x8a3f,0x6c}, + {0x8a40,0x75}, + {0x8a41,0x51}, + {0x8a42,0x0a}, + {0x8a43,0xaf}, + {0x8a44,0x51}, + {0x8a45,0x15}, + {0x8a46,0x51}, + {0x8a47,0xef}, + {0x8a48,0x70}, + {0x8a49,0xf9}, + {0x8a4a,0xc2}, + {0x8a4b,0x29}, + {0x8a4c,0x12}, + {0x8a4d,0x01}, + {0x8a4e,0x6c}, + {0x8a4f,0x75}, + {0x8a50,0x51}, + {0x8a51,0x05}, + {0x8a52,0xaf}, + {0x8a53,0x51}, + {0x8a54,0x15}, + {0x8a55,0x51}, + {0x8a56,0xef}, + {0x8a57,0x70}, + {0x8a58,0xf9}, + {0x8a59,0xc2}, + {0x8a5a,0x28}, + {0x8a5b,0x12}, + {0x8a5c,0x01}, + {0x8a5d,0x6c}, + {0x8a5e,0x75}, + {0x8a5f,0x51}, + {0x8a60,0x05}, + {0x8a61,0xaf}, + {0x8a62,0x51}, + {0x8a63,0x15}, + {0x8a64,0x51}, + {0x8a65,0xef}, + {0x8a66,0x70}, + {0x8a67,0xf9}, + {0x8a68,0x75}, + {0x8a69,0x10}, + {0x8a6a,0x18}, + {0x8a6b,0x12}, + {0x8a6c,0x0b}, + {0x8a6d,0x5d}, + {0x8a6e,0x75}, + {0x8a6f,0x51}, + {0x8a70,0x0a}, + {0x8a71,0xaf}, + {0x8a72,0x51}, + {0x8a73,0x15}, + {0x8a74,0x51}, + {0x8a75,0xef}, + {0x8a76,0x70}, + {0x8a77,0xf9}, + {0x8a78,0xd2}, + {0x8a79,0x28}, + {0x8a7a,0x12}, + {0x8a7b,0x01}, + {0x8a7c,0x6c}, + {0x8a7d,0x12}, + {0x8a7e,0x02}, + {0x8a7f,0x2f}, + {0x8a80,0xaf}, + {0x8a81,0x51}, + {0x8a82,0x15}, + {0x8a83,0x51}, + {0x8a84,0xef}, + {0x8a85,0x70}, + {0x8a86,0xf9}, + {0x8a87,0xc2}, + {0x8a88,0x28}, + {0x8a89,0x12}, + {0x8a8a,0x01}, + {0x8a8b,0x6c}, + {0x8a8c,0x75}, + {0x8a8d,0x51}, + {0x8a8e,0x0a}, + {0x8a8f,0xaf}, + {0x8a90,0x51}, + {0x8a91,0x15}, + {0x8a92,0x51}, + {0x8a93,0xef}, + {0x8a94,0x70}, + {0x8a95,0xf9}, + {0x8a96,0x30}, + {0x8a97,0x11}, + {0x8a98,0x03}, + {0x8a99,0x02}, + {0x8a9a,0x0b}, + {0x8a9b,0x14}, + {0x8a9c,0x12}, + {0x8a9d,0x01}, + {0x8a9e,0x6a}, + {0x8a9f,0x12}, + {0x8aa0,0x02}, + {0x8aa1,0x12}, + {0x8aa2,0xe5}, + {0x8aa3,0x0d}, + {0x8aa4,0xf5}, + {0x8aa5,0x10}, + {0x8aa6,0x12}, + {0x8aa7,0x0b}, + {0x8aa8,0x5d}, + {0x8aa9,0x75}, + {0x8aaa,0x51}, + {0x8aab,0x0a}, + {0x8aac,0xaf}, + {0x8aad,0x51}, + {0x8aae,0x15}, + {0x8aaf,0x51}, + {0x8ab0,0xef}, + {0x8ab1,0x70}, + {0x8ab2,0xf9}, + {0x8ab3,0xd2}, + {0x8ab4,0x28}, + {0x8ab5,0x12}, + {0x8ab6,0x01}, + {0x8ab7,0x6c}, + {0x8ab8,0x12}, + {0x8ab9,0x02}, + {0x8aba,0x2f}, + {0x8abb,0xaf}, + {0x8abc,0x51}, + {0x8abd,0x15}, + {0x8abe,0x51}, + {0x8abf,0xef}, + {0x8ac0,0x70}, + {0x8ac1,0xf9}, + {0x8ac2,0xc2}, + {0x8ac3,0x28}, + {0x8ac4,0x12}, + {0x8ac5,0x01}, + {0x8ac6,0x6c}, + {0x8ac7,0x75}, + {0x8ac8,0x51}, + {0x8ac9,0x0a}, + {0x8aca,0xaf}, + {0x8acb,0x51}, + {0x8acc,0x15}, + {0x8acd,0x51}, + {0x8ace,0xef}, + {0x8acf,0x70}, + {0x8ad0,0xf9}, + {0x8ad1,0x30}, + {0x8ad2,0x11}, + {0x8ad3,0x04}, + {0x8ad4,0x15}, + {0x8ad5,0x0f}, + {0x8ad6,0x80}, + {0x8ad7,0x45}, + {0x8ad8,0x12}, + {0x8ad9,0x01}, + {0x8ada,0x6a}, + {0x8adb,0x12}, + {0x8adc,0x02}, + {0x8add,0x12}, + {0x8ade,0x85}, + {0x8adf,0x0e}, + {0x8ae0,0x10}, + {0x8ae1,0x12}, + {0x8ae2,0x15}, + {0x8ae3,0xa4}, + {0x8ae4,0xc2}, + {0x8ae5,0x09}, + {0x8ae6,0x12}, + {0x8ae7,0x02}, + {0x8ae8,0x14}, + {0x8ae9,0x75}, + {0x8aea,0x51}, + {0x8aeb,0x0a}, + {0x8aec,0xaf}, + {0x8aed,0x51}, + {0x8aee,0x15}, + {0x8aef,0x51}, + {0x8af0,0xef}, + {0x8af1,0x70}, + {0x8af2,0xf9}, + {0x8af3,0xd2}, + {0x8af4,0x28}, + {0x8af5,0x12}, + {0x8af6,0x01}, + {0x8af7,0x6c}, + {0x8af8,0x12}, + {0x8af9,0x02}, + {0x8afa,0x2f}, + {0x8afb,0xaf}, + {0x8afc,0x51}, + {0x8afd,0x15}, + {0x8afe,0x51}, + {0x8aff,0xef}, + {0x8b00,0x70}, + {0x8b01,0xf9}, + {0x8b02,0xc2}, + {0x8b03,0x28}, + {0x8b04,0x12}, + {0x8b05,0x01}, + {0x8b06,0x6c}, + {0x8b07,0x75}, + {0x8b08,0x51}, + {0x8b09,0x0a}, + {0x8b0a,0xaf}, + {0x8b0b,0x51}, + {0x8b0c,0x15}, + {0x8b0d,0x51}, + {0x8b0e,0xef}, + {0x8b0f,0x70}, + {0x8b10,0xf9}, + {0x8b11,0x30}, + {0x8b12,0x11}, + {0x8b13,0x06}, + {0x8b14,0x15}, + {0x8b15,0x0f}, + {0x8b16,0xd2}, + {0x8b17,0x33}, + {0x8b18,0x80}, + {0x8b19,0x03}, + {0x8b1a,0xe4}, + {0x8b1b,0xf5}, + {0x8b1c,0x0f}, + {0x8b1d,0x12}, + {0x8b1e,0x01}, + {0x8b1f,0x6a}, + {0x8b20,0x12}, + {0x8b21,0x02}, + {0x8b22,0x12}, + {0x8b23,0xc2}, + {0x8b24,0x29}, + {0x8b25,0x12}, + {0x8b26,0x01}, + {0x8b27,0x6c}, + {0x8b28,0x75}, + {0x8b29,0x51}, + {0x8b2a,0x05}, + {0x8b2b,0xaf}, + {0x8b2c,0x51}, + {0x8b2d,0x15}, + {0x8b2e,0x51}, + {0x8b2f,0xef}, + {0x8b30,0x70}, + {0x8b31,0xf9}, + {0x8b32,0xd2}, + {0x8b33,0x28}, + {0x8b34,0x12}, + {0x8b35,0x01}, + {0x8b36,0x6c}, + {0x8b37,0x75}, + {0x8b38,0x51}, + {0x8b39,0x05}, + {0x8b3a,0xaf}, + {0x8b3b,0x51}, + {0x8b3c,0x15}, + {0x8b3d,0x51}, + {0x8b3e,0xef}, + {0x8b3f,0x70}, + {0x8b40,0xf9}, + {0x8b41,0x12}, + {0x8b42,0x01}, + {0x8b43,0x6a}, + {0x8b44,0x75}, + {0x8b45,0x51}, + {0x8b46,0x05}, + {0x8b47,0xaf}, + {0x8b48,0x51}, + {0x8b49,0x15}, + {0x8b4a,0x51}, + {0x8b4b,0xef}, + {0x8b4c,0x70}, + {0x8b4d,0xf9}, + {0x8b4e,0xa2}, + {0x8b4f,0x32}, + {0x8b50,0x92}, + {0x8b51,0xaf}, + {0x8b52,0xe5}, + {0x8b53,0x0f}, + {0x8b54,0xd3}, + {0x8b55,0x94}, + {0x8b56,0x00}, + {0x8b57,0x40}, + {0x8b58,0x03}, + {0x8b59,0x02}, + {0x8b5a,0x0a}, + {0x8b5b,0x24}, + {0x8b5c,0x22}, + {0x8b5d,0x12}, + {0x8b5e,0x15}, + {0x8b5f,0xa4}, + {0x8b60,0xc2}, + {0x8b61,0x09}, + {0x8b62,0x90}, + {0x8b63,0x30}, + {0x8b64,0x18}, + {0x8b65,0xe5}, + {0x8b66,0x21}, + {0x8b67,0xf0}, + {0x8b68,0x22}, + {0x8b69,0xe5}, + {0x8b6a,0x33}, + {0x8b6b,0x70}, + {0x8b6c,0x03}, + {0x8b6d,0x02}, + {0x8b6e,0x0c}, + {0x8b6f,0xa3}, + {0x8b70,0xc2}, + {0x8b71,0xaf}, + {0x8b72,0xaf}, + {0x8b73,0x33}, + {0x8b74,0xe4}, + {0x8b75,0xf5}, + {0x8b76,0x33}, + {0x8b77,0xd2}, + {0x8b78,0xaf}, + {0x8b79,0x90}, + {0x8b7a,0x30}, + {0x8b7b,0x25}, + {0x8b7c,0xe0}, + {0x8b7d,0xf5}, + {0x8b7e,0x7e}, + {0x8b7f,0x90}, + {0x8b80,0x50}, + {0x8b81,0x82}, + {0x8b82,0xe0}, + {0x8b83,0xf5}, + {0x8b84,0x66}, + {0x8b85,0xa3}, + {0x8b86,0xe0}, + {0x8b87,0xf5}, + {0x8b88,0x67}, + {0x8b89,0xa3}, + {0x8b8a,0xe0}, + {0x8b8b,0xf5}, + {0x8b8c,0x68}, + {0x8b8d,0xa3}, + {0x8b8e,0xe0}, + {0x8b8f,0xf5}, + {0x8b90,0x69}, + {0x8b91,0xef}, + {0x8b92,0x12}, + {0x8b93,0x09}, + {0x8b94,0xf7}, + {0x8b95,0x0b}, + {0x8b96,0xbd}, + {0x8b97,0x03}, + {0x8b98,0x0b}, + {0x8b99,0xdb}, + {0x8b9a,0x04}, + {0x8b9b,0x0b}, + {0x8b9c,0xfc}, + {0x8b9d,0x05}, + {0x8b9e,0x0c}, + {0x8b9f,0x26}, + {0x8ba0,0x06}, + {0x8ba1,0x0c}, + {0x8ba2,0x14}, + {0x8ba3,0x08}, + {0x8ba4,0x0c}, + {0x8ba5,0x33}, + {0x8ba6,0x10}, + {0x8ba7,0x0c}, + {0x8ba8,0x47}, + {0x8ba9,0x12}, + {0x8baa,0x0c}, + {0x8bab,0x4c}, + {0x8bac,0x20}, + {0x8bad,0x0c}, + {0x8bae,0x5a}, + {0x8baf,0x21}, + {0x8bb0,0x0c}, + {0x8bb1,0x5f}, + {0x8bb2,0x30}, + {0x8bb3,0x0c}, + {0x8bb4,0x88}, + {0x8bb5,0x50}, + {0x8bb6,0x0c}, + {0x8bb7,0x6a}, + {0x8bb8,0xd8}, + {0x8bb9,0x00}, + {0x8bba,0x00}, + {0x8bbb,0x0c}, + {0x8bbc,0x95}, + {0x8bbd,0x20}, + {0x8bbe,0x05}, + {0x8bbf,0x03}, + {0x8bc0,0x02}, + {0x8bc1,0x0c}, + {0x8bc2,0x95}, + {0x8bc3,0x30}, + {0x8bc4,0x00}, + {0x8bc5,0x03}, + {0x8bc6,0x02}, + {0x8bc7,0x0c}, + {0x8bc8,0x95}, + {0x8bc9,0x20}, + {0x8bca,0x07}, + {0x8bcb,0x06}, + {0x8bcc,0x20}, + {0x8bcd,0x06}, + {0x8bce,0x03}, + {0x8bcf,0xc3}, + {0x8bd0,0x80}, + {0x8bd1,0x01}, + {0x8bd2,0xd3}, + {0x8bd3,0x92}, + {0x8bd4,0x36}, + {0x8bd5,0xd2}, + {0x8bd6,0x07}, + {0x8bd7,0xc2}, + {0x8bd8,0x06}, + {0x8bd9,0x80}, + {0x8bda,0x1c}, + {0x8bdb,0x20}, + {0x8bdc,0x05}, + {0x8bdd,0x03}, + {0x8bde,0x02}, + {0x8bdf,0x0c}, + {0x8be0,0x95}, + {0x8be1,0x30}, + {0x8be2,0x00}, + {0x8be3,0x03}, + {0x8be4,0x02}, + {0x8be5,0x0c}, + {0x8be6,0x95}, + {0x8be7,0x20}, + {0x8be8,0x07}, + {0x8be9,0x06}, + {0x8bea,0x20}, + {0x8beb,0x06}, + {0x8bec,0x03}, + {0x8bed,0xc3}, + {0x8bee,0x80}, + {0x8bef,0x01}, + {0x8bf0,0xd3}, + {0x8bf1,0x92}, + {0x8bf2,0x36}, + {0x8bf3,0xd2}, + {0x8bf4,0x07}, + {0x8bf5,0xd2}, + {0x8bf6,0x06}, + {0x8bf7,0x12}, + {0x8bf8,0x02}, + {0x8bf9,0x8a}, + {0x8bfa,0x80}, + {0x8bfb,0x24}, + {0x8bfc,0x20}, + {0x8bfd,0x05}, + {0x8bfe,0x03}, + {0x8bff,0x02}, + {0x8c00,0x0c}, + {0x8c01,0x95}, + {0x8c02,0x30}, + {0x8c03,0x00}, + {0x8c04,0x03}, + {0x8c05,0x02}, + {0x8c06,0x0c}, + {0x8c07,0x95}, + {0x8c08,0xc2}, + {0x8c09,0x07}, + {0x8c0a,0xd2}, + {0x8c0b,0x06}, + {0x8c0c,0x12}, + {0x8c0d,0x02}, + {0x8c0e,0x9b}, + {0x8c0f,0xc2}, + {0x8c10,0x04}, + {0x8c11,0x02}, + {0x8c12,0x0c}, + {0x8c13,0x95}, + {0x8c14,0x12}, + {0x8c15,0x02}, + {0x8c16,0x51}, + {0x8c17,0x30}, + {0x8c18,0x05}, + {0x8c19,0x06}, + {0x8c1a,0xe4}, + {0x8c1b,0xf5}, + {0x8c1c,0x0c}, + {0x8c1d,0x12}, + {0x8c1e,0x13}, + {0x8c1f,0x64}, + {0x8c20,0xc2}, + {0x8c21,0x31}, + {0x8c22,0xd2}, + {0x8c23,0x34}, + {0x8c24,0x80}, + {0x8c25,0x6f}, + {0x8c26,0x30}, + {0x8c27,0x07}, + {0x8c28,0x6c}, + {0x8c29,0x30}, + {0x8c2a,0x06}, + {0x8c2b,0x69}, + {0x8c2c,0x12}, + {0x8c2d,0x02}, + {0x8c2e,0x8a}, + {0x8c2f,0xd2}, + {0x8c30,0x31}, + {0x8c31,0x80}, + {0x8c32,0x62}, + {0x8c33,0x20}, + {0x8c34,0x07}, + {0x8c35,0x03}, + {0x8c36,0x30}, + {0x8c37,0x06}, + {0x8c38,0x09}, + {0x8c39,0xe5}, + {0x8c3a,0x7e}, + {0x8c3b,0x64}, + {0x8c3c,0x0e}, + {0x8c3d,0x70}, + {0x8c3e,0x56}, + {0x8c3f,0x20}, + {0x8c40,0x00}, + {0x8c41,0x53}, + {0x8c42,0x12}, + {0x8c43,0x05}, + {0x8c44,0x2f}, + {0x8c45,0x80}, + {0x8c46,0x4e}, + {0x8c47,0x12}, + {0x8c48,0x06}, + {0x8c49,0xf8}, + {0x8c4a,0x80}, + {0x8c4b,0x49}, + {0x8c4c,0x30}, + {0x8c4d,0x05}, + {0x8c4e,0x46}, + {0x8c4f,0x20}, + {0x8c50,0x07}, + {0x8c51,0x43}, + {0x8c52,0x20}, + {0x8c53,0x06}, + {0x8c54,0x40}, + {0x8c55,0x12}, + {0x8c56,0x16}, + {0x8c57,0xc4}, + {0x8c58,0x80}, + {0x8c59,0x3b}, + {0x8c5a,0x12}, + {0x8c5b,0x10}, + {0x8c5c,0xfe}, + {0x8c5d,0x80}, + {0x8c5e,0x36}, + {0x8c5f,0x20}, + {0x8c60,0x07}, + {0x8c61,0x33}, + {0x8c62,0x20}, + {0x8c63,0x06}, + {0x8c64,0x30}, + {0x8c65,0x12}, + {0x8c66,0x16}, + {0x8c67,0xd3}, + {0x8c68,0x80}, + {0x8c69,0x2b}, + {0x8c6a,0xe5}, + {0x8c6b,0x7e}, + {0x8c6c,0x64}, + {0x8c6d,0x01}, + {0x8c6e,0x70}, + {0x8c6f,0x25}, + {0x8c70,0xd2}, + {0x8c71,0x35}, + {0x8c72,0x90}, + {0x8c73,0x50}, + {0x8c74,0x82}, + {0x8c75,0xe5}, + {0x8c76,0x74}, + {0x8c77,0xf0}, + {0x8c78,0xa3}, + {0x8c79,0xe5}, + {0x8c7a,0x75}, + {0x8c7b,0xf0}, + {0x8c7c,0xa3}, + {0x8c7d,0xe5}, + {0x8c7e,0x76}, + {0x8c7f,0xf0}, + {0x8c80,0xa3}, + {0x8c81,0xe5}, + {0x8c82,0x77}, + {0x8c83,0xf0}, + {0x8c84,0xc2}, + {0x8c85,0x35}, + {0x8c86,0x80}, + {0x8c87,0x0d}, + {0x8c88,0x90}, + {0x8c89,0x50}, + {0x8c8a,0x82}, + {0x8c8b,0x30}, + {0x8c8c,0x33}, + {0x8c8d,0x05}, + {0x8c8e,0x74}, + {0x8c8f,0x55}, + {0x8c90,0xf0}, + {0x8c91,0x80}, + {0x8c92,0x02}, + {0x8c93,0xe4}, + {0x8c94,0xf0}, + {0x8c95,0x20}, + {0x8c96,0x07}, + {0x8c97,0x06}, + {0x8c98,0x30}, + {0x8c99,0x06}, + {0x8c9a,0x03}, + {0x8c9b,0x30}, + {0x8c9c,0x04}, + {0x8c9d,0x05}, + {0x8c9e,0x90}, + {0x8c9f,0x30}, + {0x8ca0,0x25}, + {0x8ca1,0xe4}, + {0x8ca2,0xf0}, + {0x8ca3,0x22}, + {0x8ca4,0xc0}, + {0x8ca5,0xe0}, + {0x8ca6,0xc0}, + {0x8ca7,0xf0}, + {0x8ca8,0xc0}, + {0x8ca9,0x83}, + {0x8caa,0xc0}, + {0x8cab,0x82}, + {0x8cac,0xc0}, + {0x8cad,0xd0}, + {0x8cae,0x75}, + {0x8caf,0xd0}, + {0x8cb0,0x00}, + {0x8cb1,0xc0}, + {0x8cb2,0x00}, + {0x8cb3,0xc0}, + {0x8cb4,0x01}, + {0x8cb5,0xc0}, + {0x8cb6,0x02}, + {0x8cb7,0xc0}, + {0x8cb8,0x03}, + {0x8cb9,0xc0}, + {0x8cba,0x04}, + {0x8cbb,0xc0}, + {0x8cbc,0x05}, + {0x8cbd,0xc0}, + {0x8cbe,0x06}, + {0x8cbf,0xc0}, + {0x8cc0,0x07}, + {0x8cc1,0x90}, + {0x8cc2,0x3f}, + {0x8cc3,0x0c}, + {0x8cc4,0xe0}, + {0x8cc5,0xf5}, + {0x8cc6,0x08}, + {0x8cc7,0xe5}, + {0x8cc8,0x08}, + {0x8cc9,0x20}, + {0x8cca,0xe3}, + {0x8ccb,0x03}, + {0x8ccc,0x02}, + {0x8ccd,0x0d}, + {0x8cce,0x55}, + {0x8ccf,0x30}, + {0x8cd0,0x35}, + {0x8cd1,0x03}, + {0x8cd2,0x02}, + {0x8cd3,0x0d}, + {0x8cd4,0x55}, + {0x8cd5,0x90}, + {0x8cd6,0x60}, + {0x8cd7,0x16}, + {0x8cd8,0xe0}, + {0x8cd9,0xf5}, + {0x8cda,0x6a}, + {0x8cdb,0xa3}, + {0x8cdc,0xe0}, + {0x8cdd,0xf5}, + {0x8cde,0x6b}, + {0x8cdf,0x90}, + {0x8ce0,0x60}, + {0x8ce1,0x1e}, + {0x8ce2,0xe0}, + {0x8ce3,0xf5}, + {0x8ce4,0x6c}, + {0x8ce5,0xa3}, + {0x8ce6,0xe0}, + {0x8ce7,0xf5}, + {0x8ce8,0x6d}, + {0x8ce9,0x90}, + {0x8cea,0x60}, + {0x8ceb,0x26}, + {0x8cec,0xe0}, + {0x8ced,0xf5}, + {0x8cee,0x6e}, + {0x8cef,0xa3}, + {0x8cf0,0xe0}, + {0x8cf1,0xf5}, + {0x8cf2,0x6f}, + {0x8cf3,0x90}, + {0x8cf4,0x60}, + {0x8cf5,0x2e}, + {0x8cf6,0xe0}, + {0x8cf7,0xf5}, + {0x8cf8,0x70}, + {0x8cf9,0xa3}, + {0x8cfa,0xe0}, + {0x8cfb,0xf5}, + {0x8cfc,0x71}, + {0x8cfd,0x90}, + {0x8cfe,0x60}, + {0x8cff,0x36}, + {0x8d00,0x12}, + {0x8d01,0x00}, + {0x8d02,0x16}, + {0x8d03,0x12}, + {0x8d04,0x01}, + {0x8d05,0xc9}, + {0x8d06,0x40}, + {0x8d07,0x06}, + {0x8d08,0x75}, + {0x8d09,0x2a}, + {0x8d0a,0xff}, + {0x8d0b,0x75}, + {0x8d0c,0x2b}, + {0x8d0d,0xff}, + {0x8d0e,0x85}, + {0x8d0f,0x2a}, + {0x8d10,0x74}, + {0x8d11,0x85}, + {0x8d12,0x2b}, + {0x8d13,0x75}, + {0x8d14,0x90}, + {0x8d15,0x60}, + {0x8d16,0x1a}, + {0x8d17,0xe0}, + {0x8d18,0xf5}, + {0x8d19,0x6a}, + {0x8d1a,0xa3}, + {0x8d1b,0xe0}, + {0x8d1c,0xf5}, + {0x8d1d,0x6b}, + {0x8d1e,0x90}, + {0x8d1f,0x60}, + {0x8d20,0x22}, + {0x8d21,0xe0}, + {0x8d22,0xf5}, + {0x8d23,0x6c}, + {0x8d24,0xa3}, + {0x8d25,0xe0}, + {0x8d26,0xf5}, + {0x8d27,0x6d}, + {0x8d28,0x90}, + {0x8d29,0x60}, + {0x8d2a,0x2a}, + {0x8d2b,0xe0}, + {0x8d2c,0xf5}, + {0x8d2d,0x6e}, + {0x8d2e,0xa3}, + {0x8d2f,0xe0}, + {0x8d30,0xf5}, + {0x8d31,0x6f}, + {0x8d32,0x90}, + {0x8d33,0x60}, + {0x8d34,0x32}, + {0x8d35,0xe0}, + {0x8d36,0xf5}, + {0x8d37,0x70}, + {0x8d38,0xa3}, + {0x8d39,0xe0}, + {0x8d3a,0xf5}, + {0x8d3b,0x71}, + {0x8d3c,0x90}, + {0x8d3d,0x60}, + {0x8d3e,0x3a}, + {0x8d3f,0x12}, + {0x8d40,0x00}, + {0x8d41,0x16}, + {0x8d42,0x12}, + {0x8d43,0x01}, + {0x8d44,0xc9}, + {0x8d45,0x40}, + {0x8d46,0x06}, + {0x8d47,0x75}, + {0x8d48,0x2a}, + {0x8d49,0xff}, + {0x8d4a,0x75}, + {0x8d4b,0x2b}, + {0x8d4c,0xff}, + {0x8d4d,0x85}, + {0x8d4e,0x2a}, + {0x8d4f,0x76}, + {0x8d50,0x85}, + {0x8d51,0x2b}, + {0x8d52,0x77}, + {0x8d53,0xd2}, + {0x8d54,0x3d}, + {0x8d55,0xe5}, + {0x8d56,0x08}, + {0x8d57,0x30}, + {0x8d58,0xe5}, + {0x8d59,0x44}, + {0x8d5a,0x90}, + {0x8d5b,0x56}, + {0x8d5c,0x90}, + {0x8d5d,0xe0}, + {0x8d5e,0xf5}, + {0x8d5f,0x55}, + {0x8d60,0xe5}, + {0x8d61,0x7b}, + {0x8d62,0x24}, + {0x8d63,0x02}, + {0x8d64,0xff}, + {0x8d65,0xe4}, + {0x8d66,0x33}, + {0x8d67,0xfe}, + {0x8d68,0xad}, + {0x8d69,0x55}, + {0x8d6a,0xc3}, + {0x8d6b,0xef}, + {0x8d6c,0x9d}, + {0x8d6d,0x74}, + {0x8d6e,0x80}, + {0x8d6f,0xf8}, + {0x8d70,0x6e}, + {0x8d71,0x98}, + {0x8d72,0x50}, + {0x8d73,0x02}, + {0x8d74,0x80}, + {0x8d75,0x01}, + {0x8d76,0xc3}, + {0x8d77,0x92}, + {0x8d78,0x27}, + {0x8d79,0xaf}, + {0x8d7a,0x55}, + {0x8d7b,0xef}, + {0x8d7c,0x24}, + {0x8d7d,0x02}, + {0x8d7e,0xff}, + {0x8d7f,0xe4}, + {0x8d80,0x33}, + {0x8d81,0xfe}, + {0x8d82,0xc3}, + {0x8d83,0xef}, + {0x8d84,0x95}, + {0x8d85,0x7b}, + {0x8d86,0x74}, + {0x8d87,0x80}, + {0x8d88,0xf8}, + {0x8d89,0x6e}, + {0x8d8a,0x98}, + {0x8d8b,0x50}, + {0x8d8c,0x02}, + {0x8d8d,0x80}, + {0x8d8e,0x02}, + {0x8d8f,0xa2}, + {0x8d90,0x27}, + {0x8d91,0x92}, + {0x8d92,0x27}, + {0x8d93,0x30}, + {0x8d94,0x27}, + {0x8d95,0x04}, + {0x8d96,0xaf}, + {0x8d97,0x55}, + {0x8d98,0x80}, + {0x8d99,0x02}, + {0x8d9a,0xaf}, + {0x8d9b,0x7b}, + {0x8d9c,0x8f}, + {0x8d9d,0x7b}, + {0x8d9e,0xe5}, + {0x8d9f,0x08}, + {0x8da0,0x30}, + {0x8da1,0xe1}, + {0x8da2,0x08}, + {0x8da3,0x90}, + {0x8da4,0x30}, + {0x8da5,0x24}, + {0x8da6,0xe0}, + {0x8da7,0xf5}, + {0x8da8,0x33}, + {0x8da9,0xe4}, + {0x8daa,0xf0}, + {0x8dab,0x90}, + {0x8dac,0x3f}, + {0x8dad,0x0c}, + {0x8dae,0xe5}, + {0x8daf,0x08}, + {0x8db0,0xf0}, + {0x8db1,0xd0}, + {0x8db2,0x07}, + {0x8db3,0xd0}, + {0x8db4,0x06}, + {0x8db5,0xd0}, + {0x8db6,0x05}, + {0x8db7,0xd0}, + {0x8db8,0x04}, + {0x8db9,0xd0}, + {0x8dba,0x03}, + {0x8dbb,0xd0}, + {0x8dbc,0x02}, + {0x8dbd,0xd0}, + {0x8dbe,0x01}, + {0x8dbf,0xd0}, + {0x8dc0,0x00}, + {0x8dc1,0xd0}, + {0x8dc2,0xd0}, + {0x8dc3,0xd0}, + {0x8dc4,0x82}, + {0x8dc5,0xd0}, + {0x8dc6,0x83}, + {0x8dc7,0xd0}, + {0x8dc8,0xf0}, + {0x8dc9,0xd0}, + {0x8dca,0xe0}, + {0x8dcb,0x32}, + {0x8dcc,0x30}, + {0x8dcd,0x04}, + {0x8dce,0x03}, + {0x8dcf,0x02}, + {0x8dd0,0x0e}, + {0x8dd1,0xac}, + {0x8dd2,0xd2}, + {0x8dd3,0x04}, + {0x8dd4,0xe5}, + {0x8dd5,0x7e}, + {0x8dd6,0xb4}, + {0x8dd7,0x01}, + {0x8dd8,0x06}, + {0x8dd9,0x12}, + {0x8dda,0x16}, + {0x8ddb,0xa4}, + {0x8ddc,0x02}, + {0x8ddd,0x0e}, + {0x8dde,0xa5}, + {0x8ddf,0xe5}, + {0x8de0,0x7e}, + {0x8de1,0xb4}, + {0x8de2,0x02}, + {0x8de3,0x06}, + {0x8de4,0x12}, + {0x8de5,0x16}, + {0x8de6,0xb5}, + {0x8de7,0x02}, + {0x8de8,0x0e}, + {0x8de9,0xa5}, + {0x8dea,0xe5}, + {0x8deb,0x7e}, + {0x8dec,0xb4}, + {0x8ded,0x03}, + {0x8dee,0x05}, + {0x8def,0xe4}, + {0x8df0,0xf5}, + {0x8df1,0x0c}, + {0x8df2,0x80}, + {0x8df3,0x08}, + {0x8df4,0xe5}, + {0x8df5,0x7e}, + {0x8df6,0xb4}, + {0x8df7,0x04}, + {0x8df8,0x09}, + {0x8df9,0x85}, + {0x8dfa,0x7c}, + {0x8dfb,0x0c}, + {0x8dfc,0x12}, + {0x8dfd,0x13}, + {0x8dfe,0x64}, + {0x8dff,0x02}, + {0x8e00,0x0e}, + {0x8e01,0xa5}, + {0x8e02,0xe5}, + {0x8e03,0x7e}, + {0x8e04,0x64}, + {0x8e05,0x0f}, + {0x8e06,0x70}, + {0x8e07,0x15}, + {0x8e08,0x12}, + {0x8e09,0x02}, + {0x8e0a,0xb3}, + {0x8e0b,0x40}, + {0x8e0c,0x06}, + {0x8e0d,0x7e}, + {0x8e0e,0x03}, + {0x8e0f,0x7f}, + {0x8e10,0xff}, + {0x8e11,0x80}, + {0x8e12,0x04}, + {0x8e13,0xae}, + {0x8e14,0x68}, + {0x8e15,0xaf}, + {0x8e16,0x69}, + {0x8e17,0x12}, + {0x8e18,0x0e}, + {0x8e19,0xad}, + {0x8e1a,0x02}, + {0x8e1b,0x0e}, + {0x8e1c,0xa5}, + {0x8e1d,0xe5}, + {0x8e1e,0x7e}, + {0x8e1f,0x64}, + {0x8e20,0x10}, + {0x8e21,0x60}, + {0x8e22,0x03}, + {0x8e23,0x02}, + {0x8e24,0x0e}, + {0x8e25,0xa5}, + {0x8e26,0xf5}, + {0x8e27,0x66}, + {0x8e28,0xf5}, + {0x8e29,0x67}, + {0x8e2a,0xf5}, + {0x8e2b,0x68}, + {0x8e2c,0xab}, + {0x8e2d,0x69}, + {0x8e2e,0xaa}, + {0x8e2f,0x68}, + {0x8e30,0xa9}, + {0x8e31,0x67}, + {0x8e32,0xa8}, + {0x8e33,0x66}, + {0x8e34,0x12}, + {0x8e35,0x01}, + {0x8e36,0x73}, + {0x8e37,0xfe}, + {0x8e38,0xe4}, + {0x8e39,0xfc}, + {0x8e3a,0xfd}, + {0x8e3b,0x12}, + {0x8e3c,0x01}, + {0x8e3d,0xf1}, + {0x8e3e,0xe4}, + {0x8e3f,0x7b}, + {0x8e40,0xff}, + {0x8e41,0xfa}, + {0x8e42,0xf9}, + {0x8e43,0xf8}, + {0x8e44,0x12}, + {0x8e45,0x02}, + {0x8e46,0x67}, + {0x8e47,0x12}, + {0x8e48,0x02}, + {0x8e49,0x39}, + {0x8e4a,0xe4}, + {0x8e4b,0x93}, + {0x8e4c,0xfe}, + {0x8e4d,0x74}, + {0x8e4e,0x01}, + {0x8e4f,0x93}, + {0x8e50,0xff}, + {0x8e51,0xe4}, + {0x8e52,0xfc}, + {0x8e53,0xfd}, + {0x8e54,0xe5}, + {0x8e55,0x69}, + {0x8e56,0x2f}, + {0x8e57,0xf5}, + {0x8e58,0x69}, + {0x8e59,0xe5}, + {0x8e5a,0x68}, + {0x8e5b,0x3e}, + {0x8e5c,0xf5}, + {0x8e5d,0x68}, + {0x8e5e,0xed}, + {0x8e5f,0x35}, + {0x8e60,0x67}, + {0x8e61,0xf5}, + {0x8e62,0x67}, + {0x8e63,0xec}, + {0x8e64,0x35}, + {0x8e65,0x66}, + {0x8e66,0xf5}, + {0x8e67,0x66}, + {0x8e68,0x12}, + {0x8e69,0x02}, + {0x8e6a,0xb3}, + {0x8e6b,0x40}, + {0x8e6c,0x06}, + {0x8e6d,0x7e}, + {0x8e6e,0x03}, + {0x8e6f,0x7f}, + {0x8e70,0xff}, + {0x8e71,0x80}, + {0x8e72,0x04}, + {0x8e73,0xae}, + {0x8e74,0x68}, + {0x8e75,0xaf}, + {0x8e76,0x69}, + {0x8e77,0x12}, + {0x8e78,0x0e}, + {0x8e79,0xad}, + {0x8e7a,0xe4}, + {0x8e7b,0xf5}, + {0x8e7c,0x67}, + {0x8e7d,0xf5}, + {0x8e7e,0x67}, + {0x8e7f,0xe5}, + {0x8e80,0x67}, + {0x8e81,0xd3}, + {0x8e82,0x95}, + {0x8e83,0x7c}, + {0x8e84,0x50}, + {0x8e85,0x1c}, + {0x8e86,0x12}, + {0x8e87,0x02}, + {0x8e88,0x39}, + {0x8e89,0xaf}, + {0x8e8a,0x67}, + {0x8e8b,0x75}, + {0x8e8c,0xf0}, + {0x8e8d,0x02}, + {0x8e8e,0xef}, + {0x8e8f,0x12}, + {0x8e90,0x09}, + {0x8e91,0xeb}, + {0x8e92,0xc3}, + {0x8e93,0x74}, + {0x8e94,0x01}, + {0x8e95,0x93}, + {0x8e96,0x95}, + {0x8e97,0x69}, + {0x8e98,0xe4}, + {0x8e99,0x93}, + {0x8e9a,0x95}, + {0x8e9b,0x68}, + {0x8e9c,0x50}, + {0x8e9d,0x04}, + {0x8e9e,0x05}, + {0x8e9f,0x67}, + {0x8ea0,0x80}, + {0x8ea1,0xdd}, + {0x8ea2,0x85}, + {0x8ea3,0x67}, + {0x8ea4,0x7d}, + {0x8ea5,0x90}, + {0x8ea6,0x30}, + {0x8ea7,0x25}, + {0x8ea8,0xe4}, + {0x8ea9,0xf0}, + {0x8eaa,0xd2}, + {0x8eab,0x34}, + {0x8eac,0x22}, + {0x8ead,0x8e}, + {0x8eae,0x68}, + {0x8eaf,0x8f}, + {0x8eb0,0x69}, + {0x8eb1,0x85}, + {0x8eb2,0x68}, + {0x8eb3,0x64}, + {0x8eb4,0x85}, + {0x8eb5,0x69}, + {0x8eb6,0x65}, + {0x8eb7,0xe5}, + {0x8eb8,0x69}, + {0x8eb9,0xc4}, + {0x8eba,0xf8}, + {0x8ebb,0x54}, + {0x8ebc,0x0f}, + {0x8ebd,0xc8}, + {0x8ebe,0x68}, + {0x8ebf,0xf5}, + {0x8ec0,0x69}, + {0x8ec1,0xe5}, + {0x8ec2,0x68}, + {0x8ec3,0xc4}, + {0x8ec4,0x54}, + {0x8ec5,0xf0}, + {0x8ec6,0x48}, + {0x8ec7,0xf5}, + {0x8ec8,0x68}, + {0x8ec9,0x85}, + {0x8eca,0x68}, + {0x8ecb,0x0d}, + {0x8ecc,0x85}, + {0x8ecd,0x69}, + {0x8ece,0x0e}, + {0x8ecf,0x12}, + {0x8ed0,0x0a}, + {0x8ed1,0x1d}, + {0x8ed2,0x22}, + {0x8ed3,0x12}, + {0x8ed4,0x02}, + {0x8ed5,0x7f}, + {0x8ed6,0xb5}, + {0x8ed7,0x07}, + {0x8ed8,0x03}, + {0x8ed9,0xd3}, + {0x8eda,0x80}, + {0x8edb,0x01}, + {0x8edc,0xc3}, + {0x8edd,0x40}, + {0x8ede,0x03}, + {0x8edf,0x02}, + {0x8ee0,0x0f}, + {0x8ee1,0x72}, + {0x8ee2,0x90}, + {0x8ee3,0x30}, + {0x8ee4,0x04}, + {0x8ee5,0xe0}, + {0x8ee6,0x44}, + {0x8ee7,0x20}, + {0x8ee8,0xf0}, + {0x8ee9,0xa3}, + {0x8eea,0xe0}, + {0x8eeb,0x44}, + {0x8eec,0x40}, + {0x8eed,0xf0}, + {0x8eee,0x90}, + {0x8eef,0x50}, + {0x8ef0,0x25}, + {0x8ef1,0xe0}, + {0x8ef2,0x44}, + {0x8ef3,0x04}, + {0x8ef4,0xf0}, + {0x8ef5,0x90}, + {0x8ef6,0x50}, + {0x8ef7,0x03}, + {0x8ef8,0xe0}, + {0x8ef9,0x54}, + {0x8efa,0xfd}, + {0x8efb,0xf0}, + {0x8efc,0x90}, + {0x8efd,0x50}, + {0x8efe,0x27}, + {0x8eff,0xe0}, + {0x8f00,0x44}, + {0x8f01,0x01}, + {0x8f02,0xf0}, + {0x8f03,0x90}, + {0x8f04,0x50}, + {0x8f05,0x31}, + {0x8f06,0xe4}, + {0x8f07,0xf0}, + {0x8f08,0x90}, + {0x8f09,0x50}, + {0x8f0a,0x33}, + {0x8f0b,0xf0}, + {0x8f0c,0x90}, + {0x8f0d,0x30}, + {0x8f0e,0x1e}, + {0x8f0f,0x12}, + {0x8f10,0x02}, + {0x8f11,0x05}, + {0x8f12,0x90}, + {0x8f13,0x30}, + {0x8f14,0x18}, + {0x8f15,0x12}, + {0x8f16,0x02}, + {0x8f17,0x05}, + {0x8f18,0x90}, + {0x8f19,0x30}, + {0x8f1a,0x1b}, + {0x8f1b,0x12}, + {0x8f1c,0x02}, + {0x8f1d,0x05}, + {0x8f1e,0xe0}, + {0x8f1f,0xf5}, + {0x8f20,0x25}, + {0x8f21,0x90}, + {0x8f22,0x30}, + {0x8f23,0x18}, + {0x8f24,0xe0}, + {0x8f25,0xf5}, + {0x8f26,0x21}, + {0x8f27,0x90}, + {0x8f28,0x60}, + {0x8f29,0x00}, + {0x8f2a,0x74}, + {0x8f2b,0xf5}, + {0x8f2c,0xf0}, + {0x8f2d,0x90}, + {0x8f2e,0x3f}, + {0x8f2f,0x01}, + {0x8f30,0xe4}, + {0x8f31,0xf0}, + {0x8f32,0xa3}, + {0x8f33,0xf0}, + {0x8f34,0x90}, + {0x8f35,0x3f}, + {0x8f36,0x01}, + {0x8f37,0xe0}, + {0x8f38,0x44}, + {0x8f39,0x08}, + {0x8f3a,0xf0}, + {0x8f3b,0xe0}, + {0x8f3c,0x44}, + {0x8f3d,0x20}, + {0x8f3e,0xf0}, + {0x8f3f,0x90}, + {0x8f40,0x3f}, + {0x8f41,0x05}, + {0x8f42,0x74}, + {0x8f43,0x30}, + {0x8f44,0xf0}, + {0x8f45,0xa3}, + {0x8f46,0x74}, + {0x8f47,0x24}, + {0x8f48,0xf0}, + {0x8f49,0x90}, + {0x8f4a,0x3f}, + {0x8f4b,0x0b}, + {0x8f4c,0xe0}, + {0x8f4d,0x44}, + {0x8f4e,0x0f}, + {0x8f4f,0xf0}, + {0x8f50,0x90}, + {0x8f51,0x3f}, + {0x8f52,0x01}, + {0x8f53,0xe0}, + {0x8f54,0x44}, + {0x8f55,0x02}, + {0x8f56,0xf0}, + {0x8f57,0xc2}, + {0x8f58,0x8c}, + {0x8f59,0x75}, + {0x8f5a,0x89}, + {0x8f5b,0x03}, + {0x8f5c,0x75}, + {0x8f5d,0xa8}, + {0x8f5e,0x07}, + {0x8f5f,0x75}, + {0x8f60,0xb8}, + {0x8f61,0x04}, + {0x8f62,0xe4}, + {0x8f63,0xf5}, + {0x8f64,0xd8}, + {0x8f65,0xf5}, + {0x8f66,0xe8}, + {0x8f67,0x90}, + {0x8f68,0x30}, + {0x8f69,0x01}, + {0x8f6a,0xe0}, + {0x8f6b,0x44}, + {0x8f6c,0x40}, + {0x8f6d,0xf0}, + {0x8f6e,0xe0}, + {0x8f6f,0x54}, + {0x8f70,0xbf}, + {0x8f71,0xf0}, + {0x8f72,0x22}, + {0x8f73,0x30}, + {0x8f74,0x3e}, + {0x8f75,0x09}, + {0x8f76,0x30}, + {0x8f77,0x20}, + {0x8f78,0x06}, + {0x8f79,0xae}, + {0x8f7a,0x56}, + {0x8f7b,0xaf}, + {0x8f7c,0x57}, + {0x8f7d,0x80}, + {0x8f7e,0x04}, + {0x8f7f,0xae}, + {0x8f80,0x6a}, + {0x8f81,0xaf}, + {0x8f82,0x6b}, + {0x8f83,0x8e}, + {0x8f84,0x56}, + {0x8f85,0x8f}, + {0x8f86,0x57}, + {0x8f87,0x30}, + {0x8f88,0x3e}, + {0x8f89,0x09}, + {0x8f8a,0x30}, + {0x8f8b,0x21}, + {0x8f8c,0x06}, + {0x8f8d,0xae}, + {0x8f8e,0x58}, + {0x8f8f,0xaf}, + {0x8f90,0x59}, + {0x8f91,0x80}, + {0x8f92,0x04}, + {0x8f93,0xae}, + {0x8f94,0x6c}, + {0x8f95,0xaf}, + {0x8f96,0x6d}, + {0x8f97,0x8e}, + {0x8f98,0x58}, + {0x8f99,0x8f}, + {0x8f9a,0x59}, + {0x8f9b,0x30}, + {0x8f9c,0x3e}, + {0x8f9d,0x09}, + {0x8f9e,0x30}, + {0x8f9f,0x22}, + {0x8fa0,0x06}, + {0x8fa1,0xae}, + {0x8fa2,0x5a}, + {0x8fa3,0xaf}, + {0x8fa4,0x5b}, + {0x8fa5,0x80}, + {0x8fa6,0x04}, + {0x8fa7,0xae}, + {0x8fa8,0x6e}, + {0x8fa9,0xaf}, + {0x8faa,0x6f}, + {0x8fab,0x8e}, + {0x8fac,0x5a}, + {0x8fad,0x8f}, + {0x8fae,0x5b}, + {0x8faf,0x30}, + {0x8fb0,0x3e}, + {0x8fb1,0x09}, + {0x8fb2,0x30}, + {0x8fb3,0x23}, + {0x8fb4,0x06}, + {0x8fb5,0xae}, + {0x8fb6,0x5c}, + {0x8fb7,0xaf}, + {0x8fb8,0x5d}, + {0x8fb9,0x80}, + {0x8fba,0x04}, + {0x8fbb,0xae}, + {0x8fbc,0x70}, + {0x8fbd,0xaf}, + {0x8fbe,0x71}, + {0x8fbf,0x8e}, + {0x8fc0,0x5c}, + {0x8fc1,0x8f}, + {0x8fc2,0x5d}, + {0x8fc3,0x30}, + {0x8fc4,0x3e}, + {0x8fc5,0x09}, + {0x8fc6,0x30}, + {0x8fc7,0x24}, + {0x8fc8,0x06}, + {0x8fc9,0xae}, + {0x8fca,0x5e}, + {0x8fcb,0xaf}, + {0x8fcc,0x5f}, + {0x8fcd,0x80}, + {0x8fce,0x04}, + {0x8fcf,0xae}, + {0x8fd0,0x72}, + {0x8fd1,0xaf}, + {0x8fd2,0x73}, + {0x8fd3,0x8e}, + {0x8fd4,0x5e}, + {0x8fd5,0x8f}, + {0x8fd6,0x5f}, + {0x8fd7,0x30}, + {0x8fd8,0x3e}, + {0x8fd9,0x09}, + {0x8fda,0x30}, + {0x8fdb,0x25}, + {0x8fdc,0x06}, + {0x8fdd,0xae}, + {0x8fde,0x60}, + {0x8fdf,0xaf}, + {0x8fe0,0x61}, + {0x8fe1,0x80}, + {0x8fe2,0x04}, + {0x8fe3,0xae}, + {0x8fe4,0x74}, + {0x8fe5,0xaf}, + {0x8fe6,0x75}, + {0x8fe7,0x8e}, + {0x8fe8,0x60}, + {0x8fe9,0x8f}, + {0x8fea,0x61}, + {0x8feb,0x30}, + {0x8fec,0x3e}, + {0x8fed,0x09}, + {0x8fee,0x30}, + {0x8fef,0x26}, + {0x8ff0,0x06}, + {0x8ff1,0xae}, + {0x8ff2,0x62}, + {0x8ff3,0xaf}, + {0x8ff4,0x63}, + {0x8ff5,0x80}, + {0x8ff6,0x04}, + {0x8ff7,0xae}, + {0x8ff8,0x76}, + {0x8ff9,0xaf}, + {0x8ffa,0x77}, + {0x8ffb,0x8e}, + {0x8ffc,0x62}, + {0x8ffd,0x8f}, + {0x8ffe,0x63}, + {0x8fff,0x22}, + {0x9000,0x30}, + {0x9001,0x36}, + {0x9002,0x4e}, + {0x9003,0x12}, + {0x9004,0x10}, + {0x9005,0x78}, + {0x9006,0xe5}, + {0x9007,0x32}, + {0x9008,0xd3}, + {0x9009,0x95}, + {0x900a,0x7d}, + {0x900b,0x40}, + {0x900c,0x0c}, + {0x900d,0xe5}, + {0x900e,0x32}, + {0x900f,0x04}, + {0x9010,0xf5}, + {0x9011,0x0c}, + {0x9012,0x12}, + {0x9013,0x13}, + {0x9014,0x64}, + {0x9015,0xd2}, + {0x9016,0x37}, + {0x9017,0x80}, + {0x9018,0x44}, + {0x9019,0xe5}, + {0x901a,0x7c}, + {0x901b,0xb5}, + {0x901c,0x7d}, + {0x901d,0x04}, + {0x901e,0x7f}, + {0x901f,0x01}, + {0x9020,0x80}, + {0x9021,0x02}, + {0x9022,0x7f}, + {0x9023,0x00}, + {0x9024,0xef}, + {0x9025,0x24}, + {0x9026,0xfb}, + {0x9027,0xd3}, + {0x9028,0x64}, + {0x9029,0x80}, + {0x902a,0xf8}, + {0x902b,0xe5}, + {0x902c,0x7d}, + {0x902d,0x64}, + {0x902e,0x80}, + {0x902f,0x98}, + {0x9030,0x40}, + {0x9031,0x12}, + {0x9032,0xc2}, + {0x9033,0x37}, + {0x9034,0xe5}, + {0x9035,0x7c}, + {0x9036,0xb5}, + {0x9037,0x7d}, + {0x9038,0x04}, + {0x9039,0x7f}, + {0x903a,0x01}, + {0x903b,0x80}, + {0x903c,0x02}, + {0x903d,0x7f}, + {0x903e,0x00}, + {0x903f,0xef}, + {0x9040,0x24}, + {0x9041,0xfa}, + {0x9042,0x80}, + {0x9043,0x06}, + {0x9044,0xd2}, + {0x9045,0x37}, + {0x9046,0xe5}, + {0x9047,0x7d}, + {0x9048,0x24}, + {0x9049,0x02}, + {0x904a,0xf5}, + {0x904b,0x0c}, + {0x904c,0x12}, + {0x904d,0x13}, + {0x904e,0x64}, + {0x904f,0x80}, + {0x9050,0x0c}, + {0x9051,0xe5}, + {0x9052,0x7d}, + {0x9053,0x70}, + {0x9054,0x0f}, + {0x9055,0x12}, + {0x9056,0x10}, + {0x9057,0x78}, + {0x9058,0xc2}, + {0x9059,0x03}, + {0x905a,0x12}, + {0x905b,0x16}, + {0x905c,0xa4}, + {0x905d,0xd2}, + {0x905e,0x02}, + {0x905f,0xd2}, + {0x9060,0x01}, + {0x9061,0xd2}, + {0x9062,0x00}, + {0x9063,0x22}, + {0x9064,0x30}, + {0x9065,0x03}, + {0x9066,0x08}, + {0x9067,0xc2}, + {0x9068,0x03}, + {0x9069,0xc2}, + {0x906a,0x04}, + {0x906b,0x12}, + {0x906c,0x02}, + {0x906d,0x9b}, + {0x906e,0x22}, + {0x906f,0xe4}, + {0x9070,0xf5}, + {0x9071,0x0c}, + {0x9072,0x12}, + {0x9073,0x13}, + {0x9074,0x64}, + {0x9075,0xd2}, + {0x9076,0x03}, + {0x9077,0x22}, + {0x9078,0x12}, + {0x9079,0x16}, + {0x907a,0x90}, + {0x907b,0xc2}, + {0x907c,0x3e}, + {0x907d,0x12}, + {0x907e,0x0f}, + {0x907f,0x73}, + {0x9080,0xc2}, + {0x9081,0x3e}, + {0x9082,0x12}, + {0x9083,0x13}, + {0x9084,0x01}, + {0x9085,0x22}, + {0x9086,0xd3}, + {0x9087,0xe5}, + {0x9088,0x57}, + {0x9089,0x95}, + {0x908a,0x6b}, + {0x908b,0xe5}, + {0x908c,0x56}, + {0x908d,0x95}, + {0x908e,0x6a}, + {0x908f,0x40}, + {0x9090,0x03}, + {0x9091,0xd3}, + {0x9092,0x80}, + {0x9093,0x01}, + {0x9094,0xc3}, + {0x9095,0x92}, + {0x9096,0x20}, + {0x9097,0xd3}, + {0x9098,0xe5}, + {0x9099,0x59}, + {0x909a,0x95}, + {0x909b,0x6d}, + {0x909c,0xe5}, + {0x909d,0x58}, + {0x909e,0x95}, + {0x909f,0x6c}, + {0x90a0,0x40}, + {0x90a1,0x03}, + {0x90a2,0xd3}, + {0x90a3,0x80}, + {0x90a4,0x01}, + {0x90a5,0xc3}, + {0x90a6,0x92}, + {0x90a7,0x21}, + {0x90a8,0xd3}, + {0x90a9,0xe5}, + {0x90aa,0x5b}, + {0x90ab,0x95}, + {0x90ac,0x6f}, + {0x90ad,0xe5}, + {0x90ae,0x5a}, + {0x90af,0x95}, + {0x90b0,0x6e}, + {0x90b1,0x40}, + {0x90b2,0x03}, + {0x90b3,0xd3}, + {0x90b4,0x80}, + {0x90b5,0x01}, + {0x90b6,0xc3}, + {0x90b7,0x92}, + {0x90b8,0x22}, + {0x90b9,0xd3}, + {0x90ba,0xe5}, + {0x90bb,0x5d}, + {0x90bc,0x95}, + {0x90bd,0x71}, + {0x90be,0xe5}, + {0x90bf,0x5c}, + {0x90c0,0x95}, + {0x90c1,0x70}, + {0x90c2,0x40}, + {0x90c3,0x03}, + {0x90c4,0xd3}, + {0x90c5,0x80}, + {0x90c6,0x01}, + {0x90c7,0xc3}, + {0x90c8,0x92}, + {0x90c9,0x23}, + {0x90ca,0xd3}, + {0x90cb,0xe5}, + {0x90cc,0x5f}, + {0x90cd,0x95}, + {0x90ce,0x73}, + {0x90cf,0xe5}, + {0x90d0,0x5e}, + {0x90d1,0x95}, + {0x90d2,0x72}, + {0x90d3,0x40}, + {0x90d4,0x03}, + {0x90d5,0xd3}, + {0x90d6,0x80}, + {0x90d7,0x01}, + {0x90d8,0xc3}, + {0x90d9,0x92}, + {0x90da,0x24}, + {0x90db,0xd3}, + {0x90dc,0xe5}, + {0x90dd,0x61}, + {0x90de,0x95}, + {0x90df,0x75}, + {0x90e0,0xe5}, + {0x90e1,0x60}, + {0x90e2,0x95}, + {0x90e3,0x74}, + {0x90e4,0x40}, + {0x90e5,0x03}, + {0x90e6,0xd3}, + {0x90e7,0x80}, + {0x90e8,0x01}, + {0x90e9,0xc3}, + {0x90ea,0x92}, + {0x90eb,0x25}, + {0x90ec,0xd3}, + {0x90ed,0xe5}, + {0x90ee,0x63}, + {0x90ef,0x95}, + {0x90f0,0x77}, + {0x90f1,0xe5}, + {0x90f2,0x62}, + {0x90f3,0x95}, + {0x90f4,0x76}, + {0x90f5,0x40}, + {0x90f6,0x03}, + {0x90f7,0xd3}, + {0x90f8,0x80}, + {0x90f9,0x01}, + {0x90fa,0xc3}, + {0x90fb,0x92}, + {0x90fc,0x26}, + {0x90fd,0x22}, + {0x90fe,0xe5}, + {0x90ff,0x7e}, + {0x9100,0x64}, + {0x9101,0x01}, + {0x9102,0x70}, + {0x9103,0x50}, + {0x9104,0x12}, + {0x9105,0x02}, + {0x9106,0x39}, + {0x9107,0xe5}, + {0x9108,0x7d}, + {0x9109,0x12}, + {0x910a,0x01}, + {0x910b,0x7b}, + {0x910c,0xfe}, + {0x910d,0xe4}, + {0x910e,0x8f}, + {0x910f,0x69}, + {0x9110,0x8e}, + {0x9111,0x68}, + {0x9112,0xf5}, + {0x9113,0x67}, + {0x9114,0xf5}, + {0x9115,0x66}, + {0x9116,0x12}, + {0x9117,0x01}, + {0x9118,0xfc}, + {0x9119,0x7b}, + {0x911a,0xff}, + {0x911b,0xfa}, + {0x911c,0xf9}, + {0x911d,0xf8}, + {0x911e,0x12}, + {0x911f,0x01}, + {0x9120,0xf1}, + {0x9121,0xc0}, + {0x9122,0x04}, + {0x9123,0xc0}, + {0x9124,0x05}, + {0x9125,0xc0}, + {0x9126,0x06}, + {0x9127,0xc0}, + {0x9128,0x07}, + {0x9129,0x12}, + {0x912a,0x01}, + {0x912b,0x73}, + {0x912c,0xab}, + {0x912d,0x07}, + {0x912e,0xfa}, + {0x912f,0xe4}, + {0x9130,0xf9}, + {0x9131,0xf8}, + {0x9132,0xd0}, + {0x9133,0x07}, + {0x9134,0xd0}, + {0x9135,0x06}, + {0x9136,0xd0}, + {0x9137,0x05}, + {0x9138,0xd0}, + {0x9139,0x04}, + {0x913a,0x12}, + {0x913b,0x02}, + {0x913c,0x67}, + {0x913d,0x85}, + {0x913e,0x69}, + {0x913f,0x66}, + {0x9140,0x85}, + {0x9141,0x7d}, + {0x9142,0x67}, + {0x9143,0x12}, + {0x9144,0x02}, + {0x9145,0x39}, + {0x9146,0xe5}, + {0x9147,0x7d}, + {0x9148,0x12}, + {0x9149,0x02}, + {0x914a,0x95}, + {0x914b,0xe4}, + {0x914c,0x93}, + {0x914d,0xf5}, + {0x914e,0x68}, + {0x914f,0x74}, + {0x9150,0x01}, + {0x9151,0x93}, + {0x9152,0xf5}, + {0x9153,0x69}, + {0x9154,0x90}, + {0x9155,0x50}, + {0x9156,0x82}, + {0x9157,0xe5}, + {0x9158,0x66}, + {0x9159,0xf0}, + {0x915a,0xa3}, + {0x915b,0xe5}, + {0x915c,0x67}, + {0x915d,0xf0}, + {0x915e,0xa3}, + {0x915f,0xe5}, + {0x9160,0x68}, + {0x9161,0xf0}, + {0x9162,0xa3}, + {0x9163,0xe5}, + {0x9164,0x69}, + {0x9165,0xf0}, + {0x9166,0x22}, + {0x9167,0x56}, + {0x9168,0x0c}, + {0x9169,0x04}, + {0x916a,0x00}, + {0x916b,0x00}, + {0x916c,0x00}, + {0x916d,0xc8}, + {0x916e,0x01}, + {0x916f,0x2c}, + {0x9170,0x01}, + {0x9171,0x5e}, + {0x9172,0x01}, + {0x9173,0x8b}, + {0x9174,0x01}, + {0x9175,0xb8}, + {0x9176,0x01}, + {0x9177,0xe5}, + {0x9178,0x02}, + {0x9179,0x12}, + {0x917a,0x02}, + {0x917b,0x3f}, + {0x917c,0x02}, + {0x917d,0x6c}, + {0x917e,0x02}, + {0x917f,0x99}, + {0x9180,0x02}, + {0x9181,0xc6}, + {0x9182,0x02}, + {0x9183,0xf3}, + {0x9184,0x07}, + {0x9185,0x20}, + {0x9186,0x12}, + {0x9187,0x28}, + {0x9188,0x1e}, + {0x9189,0x18}, + {0x918a,0x18}, + {0x918b,0x28}, + {0x918c,0x1e}, + {0x918d,0x18}, + {0x918e,0x12}, + {0x918f,0x28}, + {0x9190,0x1e}, + {0x9191,0x18}, + {0x9192,0x12}, + {0x9193,0x28}, + {0x9194,0x18}, + {0x9195,0x18}, + {0x9196,0x12}, + {0x9197,0x20}, + {0x9198,0x18}, + {0x9199,0x28}, + {0x919a,0x1c}, + {0x919b,0x30}, + {0x919c,0x24}, + {0x919d,0x10}, + {0x919e,0x1c}, + {0x919f,0x18}, + {0x91a0,0x24}, + {0x91a1,0x1c}, + {0x91a2,0x14}, + {0x91a3,0x24}, + {0x91a4,0x1c}, + {0x91a5,0x28}, + {0x91a6,0x0c}, + {0x91a7,0x30}, + {0x91a8,0x14}, + {0x91a9,0x10}, + {0x91aa,0x0c}, + {0x91ab,0x18}, + {0x91ac,0x14}, + {0x91ad,0x1c}, + {0x91ae,0x20}, + {0x91af,0x24}, + {0x91b0,0x28}, + {0x91b1,0x0c}, + {0x91b2,0x14}, + {0x91b3,0x14}, + {0x91b4,0x1c}, + {0x91b5,0x1c}, + {0x91b6,0x14}, + {0x91b7,0x24}, + {0x91b8,0x1c}, + {0x91b9,0x2c}, + {0x91ba,0x14}, + {0x91bb,0x34}, + {0x91bc,0x1c}, + {0x91bd,0x1c}, + {0x91be,0x08}, + {0x91bf,0x24}, + {0x91c0,0x10}, + {0x91c1,0x19}, + {0x91c2,0x19}, + {0x91c3,0x1c}, + {0x91c4,0x19}, + {0x91c5,0x19}, + {0x91c6,0x10}, + {0x91c7,0x10}, + {0x91c8,0x10}, + {0x91c9,0x10}, + {0x91ca,0x10}, + {0x91cb,0x00}, + {0x91cc,0x00}, + {0x91cd,0x00}, + {0x91ce,0x00}, + {0x91cf,0x00}, + {0x91d0,0x12}, + {0x91d1,0x10}, + {0x91d2,0x86}, + {0x91d3,0x30}, + {0x91d4,0x36}, + {0x91d5,0x40}, + {0x91d6,0xe5}, + {0x91d7,0x24}, + {0x91d8,0x54}, + {0x91d9,0x1f}, + {0x91da,0xff}, + {0x91db,0x60}, + {0x91dc,0x0e}, + {0x91dd,0x64}, + {0x91de,0x1f}, + {0x91df,0x60}, + {0x91e0,0x0a}, + {0x91e1,0xe5}, + {0x91e2,0x7c}, + {0x91e3,0x65}, + {0x91e4,0x7d}, + {0x91e5,0x60}, + {0x91e6,0x04}, + {0x91e7,0xe5}, + {0x91e8,0x7d}, + {0x91e9,0x70}, + {0x91ea,0x18}, + {0x91eb,0xbf}, + {0x91ec,0x1f}, + {0x91ed,0x02}, + {0x91ee,0xb2}, + {0x91ef,0x37}, + {0x91f0,0xe5}, + {0x91f1,0x7c}, + {0x91f2,0xb5}, + {0x91f3,0x7d}, + {0x91f4,0x02}, + {0x91f5,0xc2}, + {0x91f6,0x37}, + {0x91f7,0xe5}, + {0x91f8,0x7d}, + {0x91f9,0x70}, + {0x91fa,0x02}, + {0x91fb,0xd2}, + {0x91fc,0x37}, + {0x91fd,0xc2}, + {0x91fe,0x02}, + {0x91ff,0xd2}, + {0x9200,0x01}, + {0x9201,0xd2}, + {0x9202,0x00}, + {0x9203,0xc2}, + {0x9204,0x3e}, + {0x9205,0x12}, + {0x9206,0x0f}, + {0x9207,0x73}, + {0x9208,0xc2}, + {0x9209,0x3e}, + {0x920a,0x12}, + {0x920b,0x13}, + {0x920c,0x01}, + {0x920d,0x30}, + {0x920e,0x37}, + {0x920f,0x03}, + {0x9210,0x02}, + {0x9211,0x16}, + {0x9212,0xa4}, + {0x9213,0x02}, + {0x9214,0x16}, + {0x9215,0xb5}, + {0x9216,0xd2}, + {0x9217,0x3e}, + {0x9218,0x12}, + {0x9219,0x0f}, + {0x921a,0x73}, + {0x921b,0xd2}, + {0x921c,0x3e}, + {0x921d,0x12}, + {0x921e,0x13}, + {0x921f,0x01}, + {0x9220,0x12}, + {0x9221,0x16}, + {0x9222,0xa4}, + {0x9223,0xe5}, + {0x9224,0x32}, + {0x9225,0xd3}, + {0x9226,0x95}, + {0x9227,0x7d}, + {0x9228,0x40}, + {0x9229,0x05}, + {0x922a,0xe4}, + {0x922b,0x95}, + {0x922c,0x7d}, + {0x922d,0x40}, + {0x922e,0x06}, + {0x922f,0xc2}, + {0x9230,0x02}, + {0x9231,0xd2}, + {0x9232,0x01}, + {0x9233,0xd2}, + {0x9234,0x00}, + {0x9235,0x22}, + {0x9236,0x12}, + {0x9237,0x10}, + {0x9238,0x86}, + {0x9239,0xc3}, + {0x923a,0x30}, + {0x923b,0x25}, + {0x923c,0x0c}, + {0x923d,0xe5}, + {0x923e,0x61}, + {0x923f,0x95}, + {0x9240,0x75}, + {0x9241,0xff}, + {0x9242,0xe5}, + {0x9243,0x60}, + {0x9244,0x95}, + {0x9245,0x74}, + {0x9246,0xfe}, + {0x9247,0x80}, + {0x9248,0x0a}, + {0x9249,0xe5}, + {0x924a,0x75}, + {0x924b,0x95}, + {0x924c,0x61}, + {0x924d,0xff}, + {0x924e,0xe5}, + {0x924f,0x74}, + {0x9250,0x95}, + {0x9251,0x60}, + {0x9252,0xfe}, + {0x9253,0x8e}, + {0x9254,0x0a}, + {0x9255,0x8f}, + {0x9256,0x0b}, + {0x9257,0x30}, + {0x9258,0x03}, + {0x9259,0x26}, + {0x925a,0x12}, + {0x925b,0x02}, + {0x925c,0xa9}, + {0x925d,0x50}, + {0x925e,0x03}, + {0x925f,0x30}, + {0x9260,0x27}, + {0x9261,0x07}, + {0x9262,0xc2}, + {0x9263,0x3e}, + {0x9264,0x12}, + {0x9265,0x0f}, + {0x9266,0x73}, + {0x9267,0x80}, + {0x9268,0x2f}, + {0x9269,0x05}, + {0x926a,0x31}, + {0x926b,0xe5}, + {0x926c,0x31}, + {0x926d,0xd3}, + {0x926e,0x94}, + {0x926f,0x02}, + {0x9270,0x40}, + {0x9271,0x29}, + {0x9272,0xe4}, + {0x9273,0xf5}, + {0x9274,0x31}, + {0x9275,0xc2}, + {0x9276,0x03}, + {0x9277,0xc2}, + {0x9278,0x02}, + {0x9279,0xc2}, + {0x927a,0x01}, + {0x927b,0xd2}, + {0x927c,0x00}, + {0x927d,0xd2}, + {0x927e,0x34}, + {0x927f,0x22}, + {0x9280,0x12}, + {0x9281,0x02}, + {0x9282,0xa9}, + {0x9283,0x50}, + {0x9284,0x03}, + {0x9285,0x30}, + {0x9286,0x27}, + {0x9287,0x04}, + {0x9288,0x05}, + {0x9289,0x31}, + {0x928a,0x80}, + {0x928b,0x03}, + {0x928c,0xe4}, + {0x928d,0xf5}, + {0x928e,0x31}, + {0x928f,0xe5}, + {0x9290,0x31}, + {0x9291,0xd3}, + {0x9292,0x94}, + {0x9293,0x02}, + {0x9294,0x40}, + {0x9295,0x05}, + {0x9296,0xd2}, + {0x9297,0x03}, + {0x9298,0xe4}, + {0x9299,0xf5}, + {0x929a,0x31}, + {0x929b,0x22}, + {0x929c,0xe5}, + {0x929d,0x0a}, + {0x929e,0x70}, + {0x929f,0x04}, + {0x92a0,0x7a}, + {0x92a1,0x11}, + {0x92a2,0x7b}, + {0x92a3,0x85}, + {0x92a4,0xe5}, + {0x92a5,0x0a}, + {0x92a6,0xb4}, + {0x92a7,0x01}, + {0x92a8,0x04}, + {0x92a9,0x7a}, + {0x92aa,0x11}, + {0x92ab,0x7b}, + {0x92ac,0x99}, + {0x92ad,0xe5}, + {0x92ae,0x0a}, + {0x92af,0xb4}, + {0x92b0,0x02}, + {0x92b1,0x04}, + {0x92b2,0x7a}, + {0x92b3,0x11}, + {0x92b4,0x7b}, + {0x92b5,0xad}, + {0x92b6,0x8b}, + {0x92b7,0x82}, + {0x92b8,0x8a}, + {0x92b9,0x83}, + {0x92ba,0x12}, + {0x92bb,0x09}, + {0x92bc,0xdb}, + {0x92bd,0x8f}, + {0x92be,0x37}, + {0x92bf,0x8e}, + {0x92c0,0x36}, + {0x92c1,0x8d}, + {0x92c2,0x35}, + {0x92c3,0x8c}, + {0x92c4,0x34}, + {0x92c5,0xe5}, + {0x92c6,0x82}, + {0x92c7,0x24}, + {0x92c8,0x04}, + {0x92c9,0xf5}, + {0x92ca,0x82}, + {0x92cb,0xe4}, + {0x92cc,0x35}, + {0x92cd,0x83}, + {0x92ce,0xf5}, + {0x92cf,0x83}, + {0x92d0,0x12}, + {0x92d1,0x09}, + {0x92d2,0xdb}, + {0x92d3,0x8f}, + {0x92d4,0x3b}, + {0x92d5,0x8e}, + {0x92d6,0x3a}, + {0x92d7,0x8d}, + {0x92d8,0x39}, + {0x92d9,0x8c}, + {0x92da,0x38}, + {0x92db,0xeb}, + {0x92dc,0x24}, + {0x92dd,0x08}, + {0x92de,0x12}, + {0x92df,0x02}, + {0x92e0,0x40}, + {0x92e1,0x12}, + {0x92e2,0x01}, + {0x92e3,0xc0}, + {0x92e4,0xeb}, + {0x92e5,0x24}, + {0x92e6,0x0c}, + {0x92e7,0x12}, + {0x92e8,0x02}, + {0x92e9,0x40}, + {0x92ea,0x8f}, + {0x92eb,0x43}, + {0x92ec,0x8e}, + {0x92ed,0x42}, + {0x92ee,0x8d}, + {0x92ef,0x41}, + {0x92f0,0x8c}, + {0x92f1,0x40}, + {0x92f2,0xeb}, + {0x92f3,0x24}, + {0x92f4,0x10}, + {0x92f5,0x12}, + {0x92f6,0x02}, + {0x92f7,0x40}, + {0x92f8,0x8f}, + {0x92f9,0x47}, + {0x92fa,0x8e}, + {0x92fb,0x46}, + {0x92fc,0x8d}, + {0x92fd,0x45}, + {0x92fe,0x8c}, + {0x92ff,0x44}, + {0x9300,0x22}, + {0x9301,0x30}, + {0x9302,0x3e}, + {0x9303,0x07}, + {0x9304,0x30}, + {0x9305,0x20}, + {0x9306,0x04}, + {0x9307,0xaf}, + {0x9308,0x4a}, + {0x9309,0x80}, + {0x930a,0x02}, + {0x930b,0xaf}, + {0x930c,0x7d}, + {0x930d,0x8f}, + {0x930e,0x4a}, + {0x930f,0x30}, + {0x9310,0x3e}, + {0x9311,0x07}, + {0x9312,0x30}, + {0x9313,0x21}, + {0x9314,0x04}, + {0x9315,0xaf}, + {0x9316,0x4b}, + {0x9317,0x80}, + {0x9318,0x02}, + {0x9319,0xaf}, + {0x931a,0x7d}, + {0x931b,0x8f}, + {0x931c,0x4b}, + {0x931d,0x30}, + {0x931e,0x3e}, + {0x931f,0x07}, + {0x9320,0x30}, + {0x9321,0x22}, + {0x9322,0x04}, + {0x9323,0xaf}, + {0x9324,0x4c}, + {0x9325,0x80}, + {0x9326,0x02}, + {0x9327,0xaf}, + {0x9328,0x7d}, + {0x9329,0x8f}, + {0x932a,0x4c}, + {0x932b,0x30}, + {0x932c,0x3e}, + {0x932d,0x07}, + {0x932e,0x30}, + {0x932f,0x23}, + {0x9330,0x04}, + {0x9331,0xaf}, + {0x9332,0x4d}, + {0x9333,0x80}, + {0x9334,0x02}, + {0x9335,0xaf}, + {0x9336,0x7d}, + {0x9337,0x8f}, + {0x9338,0x4d}, + {0x9339,0x30}, + {0x933a,0x3e}, + {0x933b,0x07}, + {0x933c,0x30}, + {0x933d,0x24}, + {0x933e,0x04}, + {0x933f,0xaf}, + {0x9340,0x4e}, + {0x9341,0x80}, + {0x9342,0x02}, + {0x9343,0xaf}, + {0x9344,0x7d}, + {0x9345,0x8f}, + {0x9346,0x4e}, + {0x9347,0x30}, + {0x9348,0x3e}, + {0x9349,0x07}, + {0x934a,0x30}, + {0x934b,0x25}, + {0x934c,0x04}, + {0x934d,0xaf}, + {0x934e,0x4f}, + {0x934f,0x80}, + {0x9350,0x02}, + {0x9351,0xaf}, + {0x9352,0x7d}, + {0x9353,0x8f}, + {0x9354,0x4f}, + {0x9355,0x30}, + {0x9356,0x3e}, + {0x9357,0x07}, + {0x9358,0x30}, + {0x9359,0x26}, + {0x935a,0x04}, + {0x935b,0xaf}, + {0x935c,0x50}, + {0x935d,0x80}, + {0x935e,0x02}, + {0x935f,0xaf}, + {0x9360,0x7d}, + {0x9361,0x8f}, + {0x9362,0x50}, + {0x9363,0x22}, + {0x9364,0xe5}, + {0x9365,0x0c}, + {0x9366,0xd3}, + {0x9367,0x95}, + {0x9368,0x7c}, + {0x9369,0x40}, + {0x936a,0x01}, + {0x936b,0x22}, + {0x936c,0x12}, + {0x936d,0x02}, + {0x936e,0x39}, + {0x936f,0xe5}, + {0x9370,0x0c}, + {0x9371,0x12}, + {0x9372,0x02}, + {0x9373,0x95}, + {0x9374,0xe4}, + {0x9375,0x93}, + {0x9376,0xfe}, + {0x9377,0x74}, + {0x9378,0x01}, + {0x9379,0x93}, + {0x937a,0xff}, + {0x937b,0x4e}, + {0x937c,0x60}, + {0x937d,0x21}, + {0x937e,0x8e}, + {0x937f,0x64}, + {0x9380,0x8f}, + {0x9381,0x65}, + {0x9382,0xef}, + {0x9383,0xc4}, + {0x9384,0xf8}, + {0x9385,0x54}, + {0x9386,0x0f}, + {0x9387,0xc8}, + {0x9388,0x68}, + {0x9389,0xff}, + {0x938a,0xee}, + {0x938b,0xc4}, + {0x938c,0x54}, + {0x938d,0xf0}, + {0x938e,0x48}, + {0x938f,0xfe}, + {0x9390,0x43}, + {0x9391,0x07}, + {0x9392,0x0d}, + {0x9393,0x8e}, + {0x9394,0x0d}, + {0x9395,0x8f}, + {0x9396,0x0e}, + {0x9397,0x12}, + {0x9398,0x0a}, + {0x9399,0x1d}, + {0x939a,0x30}, + {0x939b,0x33}, + {0x939c,0x22}, + {0x939d,0xc3}, + {0x939e,0x22}, + {0x939f,0x75}, + {0x93a0,0x0d}, + {0x93a1,0x00}, + {0x93a2,0x75}, + {0x93a3,0x0e}, + {0x93a4,0x0d}, + {0x93a5,0x12}, + {0x93a6,0x0a}, + {0x93a7,0x1d}, + {0x93a8,0x30}, + {0x93a9,0x33}, + {0x93aa,0x02}, + {0x93ab,0xc3}, + {0x93ac,0x22}, + {0x93ad,0x75}, + {0x93ae,0x0d}, + {0x93af,0x00}, + {0x93b0,0x75}, + {0x93b1,0x0e}, + {0x93b2,0x64}, + {0x93b3,0x12}, + {0x93b4,0x16}, + {0x93b5,0x3d}, + {0x93b6,0x75}, + {0x93b7,0x0d}, + {0x93b8,0x80}, + {0x93b9,0x75}, + {0x93ba,0x0e}, + {0x93bb,0x00}, + {0x93bc,0x12}, + {0x93bd,0x0a}, + {0x93be,0x1d}, + {0x93bf,0x85}, + {0x93c0,0x0c}, + {0x93c1,0x7d}, + {0x93c2,0xd3}, + {0x93c3,0x22}, + {0x93c4,0x12}, + {0x93c5,0x10}, + {0x93c6,0x86}, + {0x93c7,0xd2}, + {0x93c8,0x3e}, + {0x93c9,0x12}, + {0x93ca,0x0f}, + {0x93cb,0x73}, + {0x93cc,0xd2}, + {0x93cd,0x3e}, + {0x93ce,0x12}, + {0x93cf,0x13}, + {0x93d0,0x01}, + {0x93d1,0x30}, + {0x93d2,0x36}, + {0x93d3,0x26}, + {0x93d4,0x30}, + {0x93d5,0x37}, + {0x93d6,0x06}, + {0x93d7,0xe5}, + {0x93d8,0x7c}, + {0x93d9,0x65}, + {0x93da,0x7d}, + {0x93db,0x60}, + {0x93dc,0x3e}, + {0x93dd,0x20}, + {0x93de,0x37}, + {0x93df,0x04}, + {0x93e0,0xe5}, + {0x93e1,0x7d}, + {0x93e2,0x60}, + {0x93e3,0x37}, + {0x93e4,0xe5}, + {0x93e5,0x24}, + {0x93e6,0x54}, + {0x93e7,0x1f}, + {0x93e8,0xff}, + {0x93e9,0xbf}, + {0x93ea,0x1f}, + {0x93eb,0x06}, + {0x93ec,0x30}, + {0x93ed,0x25}, + {0x93ee,0x03}, + {0x93ef,0x20}, + {0x93f0,0x26}, + {0x93f1,0x29}, + {0x93f2,0x30}, + {0x93f3,0x37}, + {0x93f4,0x02}, + {0x93f5,0x80}, + {0x93f6,0x21}, + {0x93f7,0x02}, + {0x93f8,0x16}, + {0x93f9,0xb5}, + {0x93fa,0xe5}, + {0x93fb,0x7c}, + {0x93fc,0xd3}, + {0x93fd,0x95}, + {0x93fe,0x7d}, + {0x93ff,0x40}, + {0x9400,0x03}, + {0x9401,0xd3}, + {0x9402,0x80}, + {0x9403,0x01}, + {0x9404,0xc3}, + {0x9405,0x50}, + {0x9406,0x14}, + {0x9407,0x20}, + {0x9408,0x39}, + {0x9409,0x0e}, + {0x940a,0xe5}, + {0x940b,0x24}, + {0x940c,0x54}, + {0x940d,0x1f}, + {0x940e,0xff}, + {0x940f,0xbf}, + {0x9410,0x1f}, + {0x9411,0x06}, + {0x9412,0x30}, + {0x9413,0x25}, + {0x9414,0x03}, + {0x9415,0x20}, + {0x9416,0x26}, + {0x9417,0x03}, + {0x9418,0x02}, + {0x9419,0x16}, + {0x941a,0xa4}, + {0x941b,0x12}, + {0x941c,0x02}, + {0x941d,0xbd}, + {0x941e,0x22}, + {0x941f,0xc2}, + {0x9420,0x34}, + {0x9421,0x20}, + {0x9422,0x05}, + {0x9423,0x05}, + {0x9424,0x75}, + {0x9425,0x0a}, + {0x9426,0xee}, + {0x9427,0x80}, + {0x9428,0x36}, + {0x9429,0x20}, + {0x942a,0x07}, + {0x942b,0x08}, + {0x942c,0x20}, + {0x942d,0x06}, + {0x942e,0x05}, + {0x942f,0xe4}, + {0x9430,0xf5}, + {0x9431,0x0a}, + {0x9432,0x80}, + {0x9433,0x2b}, + {0x9434,0x20}, + {0x9435,0x07}, + {0x9436,0x08}, + {0x9437,0x30}, + {0x9438,0x06}, + {0x9439,0x05}, + {0x943a,0x75}, + {0x943b,0x0a}, + {0x943c,0x20}, + {0x943d,0x80}, + {0x943e,0x20}, + {0x943f,0x30}, + {0x9440,0x00}, + {0x9441,0x05}, + {0x9442,0x75}, + {0x9443,0x0a}, + {0x9444,0x01}, + {0x9445,0x80}, + {0x9446,0x18}, + {0x9447,0xe5}, + {0x9448,0x20}, + {0x9449,0x54}, + {0x944a,0x07}, + {0x944b,0xff}, + {0x944c,0xbf}, + {0x944d,0x06}, + {0x944e,0x0d}, + {0x944f,0x30}, + {0x9450,0x31}, + {0x9451,0x04}, + {0x9452,0x7f}, + {0x9453,0x12}, + {0x9454,0x80}, + {0x9455,0x02}, + {0x9456,0x7f}, + {0x9457,0x02}, + {0x9458,0x8f}, + {0x9459,0x0a}, + {0x945a,0x80}, + {0x945b,0x03}, + {0x945c,0x75}, + {0x945d,0x0a}, + {0x945e,0xfe}, + {0x945f,0x90}, + {0x9460,0x30}, + {0x9461,0x27}, + {0x9462,0xe5}, + {0x9463,0x0a}, + {0x9464,0xf0}, + {0x9465,0xe5}, + {0x9466,0x23}, + {0x9467,0x54}, + {0x9468,0xf8}, + {0x9469,0xf5}, + {0x946a,0x0a}, + {0x946b,0xe5}, + {0x946c,0x79}, + {0x946d,0x25}, + {0x946e,0x0a}, + {0x946f,0xf5}, + {0x9470,0x0a}, + {0x9471,0x90}, + {0x9472,0x30}, + {0x9473,0x26}, + {0x9474,0xe5}, + {0x9475,0x0a}, + {0x9476,0xf0}, + {0x9477,0x22}, + {0x9478,0xe5}, + {0x9479,0x0a}, + {0x947a,0x70}, + {0x947b,0x04}, + {0x947c,0x7e}, + {0x947d,0x11}, + {0x947e,0x7f}, + {0x947f,0xc1}, + {0x9480,0xe5}, + {0x9481,0x0a}, + {0x9482,0xb4}, + {0x9483,0x01}, + {0x9484,0x04}, + {0x9485,0x7e}, + {0x9486,0x11}, + {0x9487,0x7f}, + {0x9488,0xc6}, + {0x9489,0xe5}, + {0x948a,0x0a}, + {0x948b,0xb4}, + {0x948c,0x02}, + {0x948d,0x04}, + {0x948e,0x7e}, + {0x948f,0x11}, + {0x9490,0x7f}, + {0x9491,0xcb}, + {0x9492,0x8f}, + {0x9493,0x82}, + {0x9494,0x8e}, + {0x9495,0x83}, + {0x9496,0xe4}, + {0x9497,0x93}, + {0x9498,0xf5}, + {0x9499,0x2c}, + {0x949a,0x74}, + {0x949b,0x01}, + {0x949c,0x93}, + {0x949d,0xf5}, + {0x949e,0x2d}, + {0x949f,0x74}, + {0x94a0,0x02}, + {0x94a1,0x93}, + {0x94a2,0xf5}, + {0x94a3,0x2e}, + {0x94a4,0x74}, + {0x94a5,0x03}, + {0x94a6,0x93}, + {0x94a7,0xf5}, + {0x94a8,0x2f}, + {0x94a9,0x74}, + {0x94aa,0x04}, + {0x94ab,0x93}, + {0x94ac,0xf5}, + {0x94ad,0x30}, + {0x94ae,0xe5}, + {0x94af,0x0a}, + {0x94b0,0xb4}, + {0x94b1,0x01}, + {0x94b2,0x07}, + {0x94b3,0x74}, + {0x94b4,0x2c}, + {0x94b5,0x25}, + {0x94b6,0x79}, + {0x94b7,0xf8}, + {0x94b8,0x76}, + {0x94b9,0x40}, + {0x94ba,0xe5}, + {0x94bb,0x0a}, + {0x94bc,0xb4}, + {0x94bd,0x02}, + {0x94be,0x07}, + {0x94bf,0x74}, + {0x94c0,0x2c}, + {0x94c1,0x25}, + {0x94c2,0x79}, + {0x94c3,0xf8}, + {0x94c4,0x76}, + {0x94c5,0x80}, + {0x94c6,0x22}, + {0x94c7,0xc2}, + {0x94c8,0xaf}, + {0x94c9,0x90}, + {0x94ca,0x30}, + {0x94cb,0x27}, + {0x94cc,0x74}, + {0x94cd,0xfa}, + {0x94ce,0xf0}, + {0x94cf,0x12}, + {0x94d0,0x0e}, + {0x94d1,0xd3}, + {0x94d2,0x12}, + {0x94d3,0x16}, + {0x94d4,0x15}, + {0x94d5,0xe4}, + {0x94d6,0xf5}, + {0x94d7,0x33}, + {0x94d8,0xd2}, + {0x94d9,0xaf}, + {0x94da,0x12}, + {0x94db,0x0b}, + {0x94dc,0x69}, + {0x94dd,0x30}, + {0x94de,0x30}, + {0x94df,0x03}, + {0x94e0,0x12}, + {0x94e1,0x06}, + {0x94e2,0xf8}, + {0x94e3,0x30}, + {0x94e4,0x34}, + {0x94e5,0x03}, + {0x94e6,0x12}, + {0x94e7,0x14}, + {0x94e8,0x1f}, + {0x94e9,0x30}, + {0x94ea,0x3d}, + {0x94eb,0xee}, + {0x94ec,0xc2}, + {0x94ed,0x3d}, + {0x94ee,0xd2}, + {0x94ef,0x35}, + {0x94f0,0x30}, + {0x94f1,0x00}, + {0x94f2,0x05}, + {0x94f3,0x12}, + {0x94f4,0x15}, + {0x94f5,0xe8}, + {0x94f6,0x80}, + {0x94f7,0x17}, + {0x94f8,0x30}, + {0x94f9,0x07}, + {0x94fa,0x0b}, + {0x94fb,0x30}, + {0x94fc,0x06}, + {0x94fd,0x08}, + {0x94fe,0x20}, + {0x94ff,0x31}, + {0x9500,0x0e}, + {0x9501,0x12}, + {0x9502,0x12}, + {0x9503,0x36}, + {0x9504,0x80}, + {0x9505,0x09}, + {0x9506,0x20}, + {0x9507,0x07}, + {0x9508,0x06}, + {0x9509,0x30}, + {0x950a,0x06}, + {0x950b,0x03}, + {0x950c,0x12}, + {0x950d,0x0d}, + {0x950e,0xcc}, + {0x950f,0xc2}, + {0x9510,0x35}, + {0x9511,0x80}, + {0x9512,0xc7}, + {0x9513,0xc0}, + {0x9514,0xe0}, + {0x9515,0xc0}, + {0x9516,0x83}, + {0x9517,0xc0}, + {0x9518,0x82}, + {0x9519,0xc0}, + {0x951a,0xd0}, + {0x951b,0x90}, + {0x951c,0x3f}, + {0x951d,0x0d}, + {0x951e,0xe0}, + {0x951f,0xf5}, + {0x9520,0x09}, + {0x9521,0xe5}, + {0x9522,0x09}, + {0x9523,0x30}, + {0x9524,0xe0}, + {0x9525,0x2e}, + {0x9526,0xe5}, + {0x9527,0x7a}, + {0x9528,0xb4}, + {0x9529,0x01}, + {0x952a,0x09}, + {0x952b,0x90}, + {0x952c,0x3a}, + {0x952d,0x00}, + {0x952e,0xe0}, + {0x952f,0xf5}, + {0x9530,0x78}, + {0x9531,0x44}, + {0x9532,0x01}, + {0x9533,0xf0}, + {0x9534,0xe5}, + {0x9535,0x7a}, + {0x9536,0xb4}, + {0x9537,0x03}, + {0x9538,0x09}, + {0x9539,0x90}, + {0x953a,0x3a}, + {0x953b,0x00}, + {0x953c,0xe0}, + {0x953d,0xf5}, + {0x953e,0x78}, + {0x953f,0x54}, + {0x9540,0xfe}, + {0x9541,0xf0}, + {0x9542,0xe5}, + {0x9543,0x7a}, + {0x9544,0xb4}, + {0x9545,0x03}, + {0x9546,0x05}, + {0x9547,0x75}, + {0x9548,0x7a}, + {0x9549,0x00}, + {0x954a,0x80}, + {0x954b,0x02}, + {0x954c,0x05}, + {0x954d,0x7a}, + {0x954e,0x90}, + {0x954f,0x3f}, + {0x9550,0x0d}, + {0x9551,0x74}, + {0x9552,0x01}, + {0x9553,0xf0}, + {0x9554,0xd0}, + {0x9555,0xd0}, + {0x9556,0xd0}, + {0x9557,0x82}, + {0x9558,0xd0}, + {0x9559,0x83}, + {0x955a,0xd0}, + {0x955b,0xe0}, + {0x955c,0x32}, + {0x955d,0x90}, + {0x955e,0x50}, + {0x955f,0x27}, + {0x9560,0xe0}, + {0x9561,0x44}, + {0x9562,0x01}, + {0x9563,0xf0}, + {0x9564,0x90}, + {0x9565,0x50}, + {0x9566,0x34}, + {0x9567,0x74}, + {0x9568,0x80}, + {0x9569,0xf0}, + {0x956a,0xa3}, + {0x956b,0x74}, + {0x956c,0x2a}, + {0x956d,0xf0}, + {0x956e,0xa3}, + {0x956f,0x74}, + {0x9570,0x14}, + {0x9571,0xf0}, + {0x9572,0x90}, + {0x9573,0x50}, + {0x9574,0x30}, + {0x9575,0xe4}, + {0x9576,0xf0}, + {0x9577,0xa3}, + {0x9578,0x74}, + {0x9579,0x02}, + {0x957a,0xf0}, + {0x957b,0xa3}, + {0x957c,0xe4}, + {0x957d,0xf0}, + {0x957e,0xa3}, + {0x957f,0x74}, + {0x9580,0x80}, + {0x9581,0xf0}, + {0x9582,0xe4}, + {0x9583,0xf5}, + {0x9584,0x0a}, + {0x9585,0x12}, + {0x9586,0x12}, + {0x9587,0x9c}, + {0x9588,0x75}, + {0x9589,0x79}, + {0x958a,0x02}, + {0x958b,0x75}, + {0x958c,0x0a}, + {0x958d,0x01}, + {0x958e,0x12}, + {0x958f,0x14}, + {0x9590,0x78}, + {0x9591,0xd2}, + {0x9592,0x18}, + {0x9593,0xd2}, + {0x9594,0x19}, + {0x9595,0xc2}, + {0x9596,0x3c}, + {0x9597,0xc2}, + {0x9598,0x3b}, + {0x9599,0xd2}, + {0x959a,0x1a}, + {0x959b,0xd2}, + {0x959c,0x38}, + {0x959d,0xd2}, + {0x959e,0x30}, + {0x959f,0xc2}, + {0x95a0,0x35}, + {0x95a1,0xc2}, + {0x95a2,0x3d}, + {0x95a3,0x22}, + {0x95a4,0x85}, + {0x95a5,0x10}, + {0x95a6,0x11}, + {0x95a7,0x7f}, + {0x95a8,0x08}, + {0x95a9,0xe5}, + {0x95aa,0x11}, + {0x95ab,0x30}, + {0x95ac,0xe7}, + {0x95ad,0x04}, + {0x95ae,0xd2}, + {0x95af,0x29}, + {0x95b0,0x80}, + {0x95b1,0x02}, + {0x95b2,0xc2}, + {0x95b3,0x29}, + {0x95b4,0x12}, + {0x95b5,0x01}, + {0x95b6,0x6c}, + {0x95b7,0x75}, + {0x95b8,0x51}, + {0x95b9,0x0a}, + {0x95ba,0xae}, + {0x95bb,0x51}, + {0x95bc,0x15}, + {0x95bd,0x51}, + {0x95be,0xee}, + {0x95bf,0x70}, + {0x95c0,0xf9}, + {0x95c1,0xe5}, + {0x95c2,0x11}, + {0x95c3,0x25}, + {0x95c4,0xe0}, + {0x95c5,0xf5}, + {0x95c6,0x11}, + {0x95c7,0xd2}, + {0x95c8,0x28}, + {0x95c9,0x12}, + {0x95ca,0x01}, + {0x95cb,0x6c}, + {0x95cc,0x75}, + {0x95cd,0x51}, + {0x95ce,0x0a}, + {0x95cf,0xae}, + {0x95d0,0x51}, + {0x95d1,0x15}, + {0x95d2,0x51}, + {0x95d3,0xee}, + {0x95d4,0x70}, + {0x95d5,0xf9}, + {0x95d6,0xc2}, + {0x95d7,0x28}, + {0x95d8,0x12}, + {0x95d9,0x01}, + {0x95da,0x6c}, + {0x95db,0x75}, + {0x95dc,0x51}, + {0x95dd,0x05}, + {0x95de,0xae}, + {0x95df,0x51}, + {0x95e0,0x15}, + {0x95e1,0x51}, + {0x95e2,0xee}, + {0x95e3,0x70}, + {0x95e4,0xf9}, + {0x95e5,0xdf}, + {0x95e6,0xc2}, + {0x95e7,0x22}, + {0x95e8,0xe5}, + {0x95e9,0x20}, + {0x95ea,0x54}, + {0x95eb,0x07}, + {0x95ec,0xff}, + {0x95ed,0xbf}, + {0x95ee,0x01}, + {0x95ef,0x03}, + {0x95f0,0x02}, + {0x95f1,0x10}, + {0x95f2,0x00}, + {0x95f3,0xe5}, + {0x95f4,0x20}, + {0x95f5,0x54}, + {0x95f6,0x07}, + {0x95f7,0xff}, + {0x95f8,0xbf}, + {0x95f9,0x07}, + {0x95fa,0x03}, + {0x95fb,0x02}, + {0x95fc,0x11}, + {0x95fd,0xd0}, + {0x95fe,0xe5}, + {0x95ff,0x20}, + {0x9600,0x54}, + {0x9601,0x07}, + {0x9602,0xff}, + {0x9603,0xbf}, + {0x9604,0x03}, + {0x9605,0x03}, + {0x9606,0x02}, + {0x9607,0x13}, + {0x9608,0xc4}, + {0x9609,0xe5}, + {0x960a,0x20}, + {0x960b,0x54}, + {0x960c,0x07}, + {0x960d,0xff}, + {0x960e,0xbf}, + {0x960f,0x05}, + {0x9610,0x03}, + {0x9611,0x12}, + {0x9612,0x16}, + {0x9613,0xe2}, + {0x9614,0x22}, + {0x9615,0x12}, + {0x9616,0x15}, + {0x9617,0x5d}, + {0x9618,0x12}, + {0x9619,0x16}, + {0x961a,0xf0}, + {0x961b,0x50}, + {0x961c,0x04}, + {0x961d,0xd2}, + {0x961e,0x05}, + {0x961f,0x80}, + {0x9620,0x02}, + {0x9621,0xc2}, + {0x9622,0x05}, + {0x9623,0x12}, + {0x9624,0x02}, + {0x9625,0x51}, + {0x9626,0xc2}, + {0x9627,0x39}, + {0x9628,0xc2}, + {0x9629,0x36}, + {0x962a,0xc2}, + {0x962b,0x31}, + {0x962c,0xd2}, + {0x962d,0x34}, + {0x962e,0x12}, + {0x962f,0x02}, + {0x9630,0x7f}, + {0x9631,0xb5}, + {0x9632,0x07}, + {0x9633,0x03}, + {0x9634,0xd3}, + {0x9635,0x80}, + {0x9636,0x01}, + {0x9637,0xc3}, + {0x9638,0x40}, + {0x9639,0x02}, + {0x963a,0xc2}, + {0x963b,0x05}, + {0x963c,0x22}, + {0x963d,0xe4}, + {0x963e,0xff}, + {0x963f,0xfe}, + {0x9640,0xc3}, + {0x9641,0xef}, + {0x9642,0x95}, + {0x9643,0x0e}, + {0x9644,0xee}, + {0x9645,0x95}, + {0x9646,0x0d}, + {0x9647,0x50}, + {0x9648,0x15}, + {0x9649,0x7d}, + {0x964a,0x8a}, + {0x964b,0x7c}, + {0x964c,0x02}, + {0x964d,0xed}, + {0x964e,0x1d}, + {0x964f,0xaa}, + {0x9650,0x04}, + {0x9651,0x70}, + {0x9652,0x01}, + {0x9653,0x1c}, + {0x9654,0x4a}, + {0x9655,0x70}, + {0x9656,0xf6}, + {0x9657,0x0f}, + {0x9658,0xbf}, + {0x9659,0x00}, + {0x965a,0x01}, + {0x965b,0x0e}, + {0x965c,0x80}, + {0x965d,0xe2}, + {0x965e,0x22}, + {0x965f,0xc2}, + {0x9660,0x03}, + {0x9661,0xd2}, + {0x9662,0x04}, + {0x9663,0x12}, + {0x9664,0x02}, + {0x9665,0x9b}, + {0x9666,0x30}, + {0x9667,0x07}, + {0x9668,0x05}, + {0x9669,0x30}, + {0x966a,0x06}, + {0x966b,0x02}, + {0x966c,0xd2}, + {0x966d,0x36}, + {0x966e,0xc2}, + {0x966f,0x3e}, + {0x9670,0x12}, + {0x9671,0x0f}, + {0x9672,0x73}, + {0x9673,0xc2}, + {0x9674,0x3e}, + {0x9675,0x12}, + {0x9676,0x13}, + {0x9677,0x01}, + {0x9678,0xd2}, + {0x9679,0x34}, + {0x967a,0x22}, + {0x967b,0x75}, + {0x967c,0x48}, + {0x967d,0x11}, + {0x967e,0x75}, + {0x967f,0x49}, + {0x9680,0x6a}, + {0x9681,0x90}, + {0x9682,0x11}, + {0x9683,0x68}, + {0x9684,0xe4}, + {0x9685,0x93}, + {0x9686,0xf5}, + {0x9687,0x7c}, + {0x9688,0xa3}, + {0x9689,0xe4}, + {0x968a,0x93}, + {0x968b,0xf5}, + {0x968c,0x32}, + {0x968d,0xc2}, + {0x968e,0x3a}, + {0x968f,0x22}, + {0x9690,0xe4}, + {0x9691,0xff}, + {0x9692,0xef}, + {0x9693,0x25}, + {0x9694,0xe0}, + {0x9695,0x24}, + {0x9696,0x56}, + {0x9697,0xf8}, + {0x9698,0xe4}, + {0x9699,0xf6}, + {0x969a,0x08}, + {0x969b,0xf6}, + {0x969c,0x0f}, + {0x969d,0xbf}, + {0x969e,0x07}, + {0x969f,0xf2}, + {0x96a0,0x53}, + {0x96a1,0x24}, + {0x96a2,0x80}, + {0x96a3,0x22}, + {0x96a4,0xe5}, + {0x96a5,0x7d}, + {0x96a6,0xc3}, + {0x96a7,0x95}, + {0x96a8,0x7c}, + {0x96a9,0x40}, + {0x96aa,0x01}, + {0x96ab,0x22}, + {0x96ac,0xe5}, + {0x96ad,0x7d}, + {0x96ae,0x04}, + {0x96af,0xf5}, + {0x96b0,0x0c}, + {0x96b1,0x12}, + {0x96b2,0x13}, + {0x96b3,0x64}, + {0x96b4,0x22}, + {0x96b5,0xe5}, + {0x96b6,0x7d}, + {0x96b7,0x70}, + {0x96b8,0x02}, + {0x96b9,0xc3}, + {0x96ba,0x22}, + {0x96bb,0xe5}, + {0x96bc,0x7d}, + {0x96bd,0x14}, + {0x96be,0xf5}, + {0x96bf,0x0c}, + {0x96c0,0x12}, + {0x96c1,0x13}, + {0x96c2,0x64}, + {0x96c3,0x22}, + {0x96c4,0xe5}, + {0x96c5,0x7e}, + {0x96c6,0xb4}, + {0x96c7,0x01}, + {0x96c8,0x09}, + {0x96c9,0x12}, + {0x96ca,0x16}, + {0x96cb,0x7b}, + {0x96cc,0xe4}, + {0x96cd,0xf5}, + {0x96ce,0x0c}, + {0x96cf,0x12}, + {0x96d0,0x13}, + {0x96d1,0x64}, + {0x96d2,0x22}, + {0x96d3,0xe5}, + {0x96d4,0x7e}, + {0x96d5,0x24}, + {0x96d6,0xfe}, + {0x96d7,0x60}, + {0x96d8,0x06}, + {0x96d9,0x04}, + {0x96da,0x70}, + {0x96db,0x05}, + {0x96dc,0xd2}, + {0x96dd,0x39}, + {0x96de,0x22}, + {0x96df,0xc2}, + {0x96e0,0x39}, + {0x96e1,0x22}, + {0x96e2,0xe5}, + {0x96e3,0x31}, + {0x96e4,0xd3}, + {0x96e5,0x94}, + {0x96e6,0x00}, + {0x96e7,0x40}, + {0x96e8,0x03}, + {0x96e9,0x15}, + {0x96ea,0x31}, + {0x96eb,0x22}, + {0x96ec,0x12}, + {0x96ed,0x16}, + {0x96ee,0x5f}, + {0x96ef,0x22}, + {0x96f0,0x12}, + {0x96f1,0x16}, + {0x96f2,0x7b}, + {0x96f3,0xe4}, + {0x96f4,0xf5}, + {0x96f5,0x0c}, + {0x96f6,0x12}, + {0x96f7,0x13}, + {0x96f8,0x64}, + {0x96f9,0x22}, + {0x3024,0x00}, + {0x3025,0x00}, + {0x5082,0x00}, + {0x5083,0x00}, + {0x5084,0x00}, + {0x5085,0x00}, + {0x3026,0x00}, + {0x3027,0xFF}, + {0x3000,0x00}, + {0x0000,0x00} +}; +#elif (VCM_DRIVER == VCM_DRIVER_DW9710) +struct reginfo sensor_af_firmware[] = +{ + {0x3000,0x20}, + {0x8000,0x02}, + {0x8001,0x00}, + {0x8002,0x06}, + {0x8003,0x02}, + {0x8004,0x0c}, + {0x8005,0x90}, + {0x8006,0x78}, + {0x8007,0x7f}, + {0x8008,0xe4}, + {0x8009,0xf6}, + {0x800a,0xd8}, + {0x800b,0xfd}, + {0x800c,0x75}, + {0x800d,0x81}, + {0x800e,0x7d}, + {0x800f,0x02}, + {0x8010,0x14}, + {0x8011,0xc7}, + {0x8012,0x00}, + {0x8013,0x02}, + {0x8014,0x15}, + {0x8015,0x13}, + {0x8016,0xe0}, + {0x8017,0xf5}, + {0x8018,0x71}, + {0x8019,0xa3}, + {0x801a,0xe0}, + {0x801b,0xf5}, + {0x801c,0x72}, + {0x801d,0xae}, + {0x801e,0x69}, + {0x801f,0xe4}, + {0x8020,0x85}, + {0x8021,0x6a}, + {0x8022,0x55}, + {0x8023,0x8e}, + {0x8024,0x54}, + {0x8025,0xf5}, + {0x8026,0x53}, + {0x8027,0xf5}, + {0x8028,0x52}, + {0x8029,0xab}, + {0x802a,0x55}, + {0x802b,0xaa}, + {0x802c,0x54}, + {0x802d,0xa9}, + {0x802e,0x53}, + {0x802f,0xa8}, + {0x8030,0x52}, + {0x8031,0xaf}, + {0x8032,0x2c}, + {0x8033,0xfc}, + {0x8034,0xfd}, + {0x8035,0xfe}, + {0x8036,0x12}, + {0x8037,0x08}, + {0x8038,0xa2}, + {0x8039,0x8f}, + {0x803a,0x55}, + {0x803b,0x8e}, + {0x803c,0x54}, + {0x803d,0x8d}, + {0x803e,0x53}, + {0x803f,0x8c}, + {0x8040,0x52}, + {0x8041,0xaf}, + {0x8042,0x55}, + {0x8043,0xae}, + {0x8044,0x54}, + {0x8045,0xad}, + {0x8046,0x53}, + {0x8047,0xac}, + {0x8048,0x52}, + {0x8049,0x8f}, + {0x804a,0x2b}, + {0x804b,0x8e}, + {0x804c,0x2a}, + {0x804d,0x8d}, + {0x804e,0x29}, + {0x804f,0x8c}, + {0x8050,0x28}, + {0x8051,0xae}, + {0x8052,0x6b}, + {0x8053,0xe4}, + {0x8054,0x85}, + {0x8055,0x6c}, + {0x8056,0x55}, + {0x8057,0x8e}, + {0x8058,0x54}, + {0x8059,0xf5}, + {0x805a,0x53}, + {0x805b,0xf5}, + {0x805c,0x52}, + {0x805d,0xab}, + {0x805e,0x55}, + {0x805f,0xaa}, + {0x8060,0x54}, + {0x8061,0xa9}, + {0x8062,0x53}, + {0x8063,0xa8}, + {0x8064,0x52}, + {0x8065,0xaf}, + {0x8066,0x2d}, + {0x8067,0xfc}, + {0x8068,0xfd}, + {0x8069,0xfe}, + {0x806a,0x12}, + {0x806b,0x08}, + {0x806c,0xa2}, + {0x806d,0x8f}, + {0x806e,0x55}, + {0x806f,0x8e}, + {0x8070,0x54}, + {0x8071,0x8d}, + {0x8072,0x53}, + {0x8073,0x8c}, + {0x8074,0x52}, + {0x8075,0xe5}, + {0x8076,0x2b}, + {0x8077,0x25}, + {0x8078,0x55}, + {0x8079,0xf5}, + {0x807a,0x2b}, + {0x807b,0xe5}, + {0x807c,0x2a}, + {0x807d,0x35}, + {0x807e,0x54}, + {0x807f,0xf5}, + {0x8080,0x2a}, + {0x8081,0xe5}, + {0x8082,0x29}, + {0x8083,0x35}, + {0x8084,0x53}, + {0x8085,0xf5}, + {0x8086,0x29}, + {0x8087,0xe5}, + {0x8088,0x28}, + {0x8089,0x35}, + {0x808a,0x52}, + {0x808b,0xf5}, + {0x808c,0x28}, + {0x808d,0xae}, + {0x808e,0x6d}, + {0x808f,0xe4}, + {0x8090,0x85}, + {0x8091,0x6e}, + {0x8092,0x55}, + {0x8093,0x8e}, + {0x8094,0x54}, + {0x8095,0xf5}, + {0x8096,0x53}, + {0x8097,0xf5}, + {0x8098,0x52}, + {0x8099,0xab}, + {0x809a,0x55}, + {0x809b,0xaa}, + {0x809c,0x54}, + {0x809d,0xa9}, + {0x809e,0x53}, + {0x809f,0xa8}, + {0x80a0,0x52}, + {0x80a1,0xaf}, + {0x80a2,0x2e}, + {0x80a3,0xfc}, + {0x80a4,0xfd}, + {0x80a5,0xfe}, + {0x80a6,0x12}, + {0x80a7,0x08}, + {0x80a8,0xa2}, + {0x80a9,0x8f}, + {0x80aa,0x55}, + {0x80ab,0x8e}, + {0x80ac,0x54}, + {0x80ad,0x8d}, + {0x80ae,0x53}, + {0x80af,0x8c}, + {0x80b0,0x52}, + {0x80b1,0xe5}, + {0x80b2,0x2b}, + {0x80b3,0x25}, + {0x80b4,0x55}, + {0x80b5,0xf5}, + {0x80b6,0x2b}, + {0x80b7,0xe5}, + {0x80b8,0x2a}, + {0x80b9,0x35}, + {0x80ba,0x54}, + {0x80bb,0xf5}, + {0x80bc,0x2a}, + {0x80bd,0xe5}, + {0x80be,0x29}, + {0x80bf,0x35}, + {0x80c0,0x53}, + {0x80c1,0xf5}, + {0x80c2,0x29}, + {0x80c3,0xe5}, + {0x80c4,0x28}, + {0x80c5,0x35}, + {0x80c6,0x52}, + {0x80c7,0xf5}, + {0x80c8,0x28}, + {0x80c9,0xae}, + {0x80ca,0x6f}, + {0x80cb,0xe4}, + {0x80cc,0x85}, + {0x80cd,0x70}, + {0x80ce,0x55}, + {0x80cf,0x8e}, + {0x80d0,0x54}, + {0x80d1,0xf5}, + {0x80d2,0x53}, + {0x80d3,0xf5}, + {0x80d4,0x52}, + {0x80d5,0xab}, + {0x80d6,0x55}, + {0x80d7,0xaa}, + {0x80d8,0x54}, + {0x80d9,0xa9}, + {0x80da,0x53}, + {0x80db,0xa8}, + {0x80dc,0x52}, + {0x80dd,0xaf}, + {0x80de,0x2f}, + {0x80df,0xfc}, + {0x80e0,0xfd}, + {0x80e1,0xfe}, + {0x80e2,0x12}, + {0x80e3,0x08}, + {0x80e4,0xa2}, + {0x80e5,0x8f}, + {0x80e6,0x55}, + {0x80e7,0x8e}, + {0x80e8,0x54}, + {0x80e9,0x8d}, + {0x80ea,0x53}, + {0x80eb,0x8c}, + {0x80ec,0x52}, + {0x80ed,0xe5}, + {0x80ee,0x2b}, + {0x80ef,0x25}, + {0x80f0,0x55}, + {0x80f1,0xf5}, + {0x80f2,0x2b}, + {0x80f3,0xe5}, + {0x80f4,0x2a}, + {0x80f5,0x35}, + {0x80f6,0x54}, + {0x80f7,0xf5}, + {0x80f8,0x2a}, + {0x80f9,0xe5}, + {0x80fa,0x29}, + {0x80fb,0x35}, + {0x80fc,0x53}, + {0x80fd,0xf5}, + {0x80fe,0x29}, + {0x80ff,0xe5}, + {0x8100,0x28}, + {0x8101,0x35}, + {0x8102,0x52}, + {0x8103,0xf5}, + {0x8104,0x28}, + {0x8105,0xae}, + {0x8106,0x71}, + {0x8107,0xe4}, + {0x8108,0x85}, + {0x8109,0x72}, + {0x810a,0x55}, + {0x810b,0x8e}, + {0x810c,0x54}, + {0x810d,0xf5}, + {0x810e,0x53}, + {0x810f,0xf5}, + {0x8110,0x52}, + {0x8111,0xab}, + {0x8112,0x55}, + {0x8113,0xaa}, + {0x8114,0x54}, + {0x8115,0xa9}, + {0x8116,0x53}, + {0x8117,0xa8}, + {0x8118,0x52}, + {0x8119,0xaf}, + {0x811a,0x30}, + {0x811b,0xfc}, + {0x811c,0xfd}, + {0x811d,0xfe}, + {0x811e,0x12}, + {0x811f,0x08}, + {0x8120,0xa2}, + {0x8121,0x8f}, + {0x8122,0x55}, + {0x8123,0x8e}, + {0x8124,0x54}, + {0x8125,0x8d}, + {0x8126,0x53}, + {0x8127,0x8c}, + {0x8128,0x52}, + {0x8129,0xe5}, + {0x812a,0x2b}, + {0x812b,0x25}, + {0x812c,0x55}, + {0x812d,0xf5}, + {0x812e,0x2b}, + {0x812f,0xe5}, + {0x8130,0x2a}, + {0x8131,0x35}, + {0x8132,0x54}, + {0x8133,0xf5}, + {0x8134,0x2a}, + {0x8135,0xe5}, + {0x8136,0x29}, + {0x8137,0x35}, + {0x8138,0x53}, + {0x8139,0xf5}, + {0x813a,0x29}, + {0x813b,0xe5}, + {0x813c,0x28}, + {0x813d,0x35}, + {0x813e,0x52}, + {0x813f,0xf5}, + {0x8140,0x28}, + {0x8141,0x22}, + {0x8142,0xab}, + {0x8143,0x0d}, + {0x8144,0xaa}, + {0x8145,0x0c}, + {0x8146,0xa9}, + {0x8147,0x0b}, + {0x8148,0xa8}, + {0x8149,0x0a}, + {0x814a,0xfc}, + {0x814b,0xfd}, + {0x814c,0xfe}, + {0x814d,0x12}, + {0x814e,0x08}, + {0x814f,0xa2}, + {0x8150,0x8f}, + {0x8151,0x0d}, + {0x8152,0x8e}, + {0x8153,0x0c}, + {0x8154,0x8d}, + {0x8155,0x0b}, + {0x8156,0x8c}, + {0x8157,0x0a}, + {0x8158,0x7b}, + {0x8159,0x40}, + {0x815a,0xe4}, + {0x815b,0xfa}, + {0x815c,0xf9}, + {0x815d,0xf8}, + {0x815e,0x12}, + {0x815f,0x09}, + {0x8160,0x2d}, + {0x8161,0x8f}, + {0x8162,0x0d}, + {0x8163,0x8e}, + {0x8164,0x0c}, + {0x8165,0x8d}, + {0x8166,0x0b}, + {0x8167,0x8c}, + {0x8168,0x0a}, + {0x8169,0x22}, + {0x816a,0xd2}, + {0x816b,0x29}, + {0x816c,0x90}, + {0x816d,0x30}, + {0x816e,0x1b}, + {0x816f,0xe5}, + {0x8170,0x25}, + {0x8171,0xf0}, + {0x8172,0x22}, + {0x8173,0xfe}, + {0x8174,0xe4}, + {0x8175,0xfc}, + {0x8176,0xfd}, + {0x8177,0xe5}, + {0x8178,0x3f}, + {0x8179,0x2f}, + {0x817a,0xf5}, + {0x817b,0x3f}, + {0x817c,0xe5}, + {0x817d,0x3e}, + {0x817e,0x3e}, + {0x817f,0xf5}, + {0x8180,0x3e}, + {0x8181,0xed}, + {0x8182,0x35}, + {0x8183,0x3d}, + {0x8184,0xf5}, + {0x8185,0x3d}, + {0x8186,0xec}, + {0x8187,0x35}, + {0x8188,0x3c}, + {0x8189,0xf5}, + {0x818a,0x3c}, + {0x818b,0xaf}, + {0x818c,0x3f}, + {0x818d,0xae}, + {0x818e,0x3e}, + {0x818f,0xfc}, + {0x8190,0xad}, + {0x8191,0x3d}, + {0x8192,0x78}, + {0x8193,0x08}, + {0x8194,0x12}, + {0x8195,0x09}, + {0x8196,0xd2}, + {0x8197,0x8f}, + {0x8198,0x3f}, + {0x8199,0x8e}, + {0x819a,0x3e}, + {0x819b,0x8d}, + {0x819c,0x3d}, + {0x819d,0x8c}, + {0x819e,0x3c}, + {0x819f,0x22}, + {0x81a0,0xe5}, + {0x81a1,0x49}, + {0x81a2,0x25}, + {0x81a3,0x7b}, + {0x81a4,0xf5}, + {0x81a5,0x82}, + {0x81a6,0xe4}, + {0x81a7,0x35}, + {0x81a8,0x48}, + {0x81a9,0xf5}, + {0x81aa,0x83}, + {0x81ab,0xe4}, + {0x81ac,0x93}, + {0x81ad,0xff}, + {0x81ae,0x85}, + {0x81af,0x49}, + {0x81b0,0x82}, + {0x81b1,0x85}, + {0x81b2,0x48}, + {0x81b3,0x83}, + {0x81b4,0xe4}, + {0x81b5,0x93}, + {0x81b6,0xfd}, + {0x81b7,0xc3}, + {0x81b8,0xef}, + {0x81b9,0x9d}, + {0x81ba,0xff}, + {0x81bb,0xe4}, + {0x81bc,0x94}, + {0x81bd,0x00}, + {0x81be,0x22}, + {0x81bf,0xaf}, + {0x81c0,0x2b}, + {0x81c1,0xae}, + {0x81c2,0x2a}, + {0x81c3,0xad}, + {0x81c4,0x29}, + {0x81c5,0xac}, + {0x81c6,0x28}, + {0x81c7,0x78}, + {0x81c8,0x06}, + {0x81c9,0x12}, + {0x81ca,0x09}, + {0x81cb,0xbf}, + {0x81cc,0x8f}, + {0x81cd,0x2b}, + {0x81ce,0x8e}, + {0x81cf,0x2a}, + {0x81d0,0x8d}, + {0x81d1,0x29}, + {0x81d2,0x8c}, + {0x81d3,0x28}, + {0x81d4,0xd3}, + {0x81d5,0xe5}, + {0x81d6,0x29}, + {0x81d7,0x94}, + {0x81d8,0x00}, + {0x81d9,0xe5}, + {0x81da,0x28}, + {0x81db,0x94}, + {0x81dc,0x00}, + {0x81dd,0x22}, + {0x81de,0xe5}, + {0x81df,0x0b}, + {0x81e0,0x24}, + {0x81e1,0x01}, + {0x81e2,0xff}, + {0x81e3,0xe4}, + {0x81e4,0x33}, + {0x81e5,0xfe}, + {0x81e6,0x22}, + {0x81e7,0x12}, + {0x81e8,0x08}, + {0x81e9,0xa2}, + {0x81ea,0x8f}, + {0x81eb,0x68}, + {0x81ec,0x8e}, + {0x81ed,0x67}, + {0x81ee,0x8d}, + {0x81ef,0x66}, + {0x81f0,0x8c}, + {0x81f1,0x65}, + {0x81f2,0xaf}, + {0x81f3,0x68}, + {0x81f4,0xae}, + {0x81f5,0x67}, + {0x81f6,0xad}, + {0x81f7,0x66}, + {0x81f8,0xac}, + {0x81f9,0x65}, + {0x81fa,0x22}, + {0x81fb,0xe0}, + {0x81fc,0x44}, + {0x81fd,0x01}, + {0x81fe,0xf0}, + {0x81ff,0xe0}, + {0x8200,0x44}, + {0x8201,0x02}, + {0x8202,0xf0}, + {0x8203,0xe0}, + {0x8204,0x44}, + {0x8205,0x04}, + {0x8206,0xf0}, + {0x8207,0x22}, + {0x8208,0xd2}, + {0x8209,0x09}, + {0x820a,0x90}, + {0x820b,0x30}, + {0x820c,0x18}, + {0x820d,0xe5}, + {0x820e,0x21}, + {0x820f,0xf0}, + {0x8210,0x22}, + {0x8211,0xe4}, + {0x8212,0x85}, + {0x8213,0x11}, + {0x8214,0x0d}, + {0x8215,0x85}, + {0x8216,0x10}, + {0x8217,0x0c}, + {0x8218,0xf5}, + {0x8219,0x0b}, + {0x821a,0xf5}, + {0x821b,0x0a}, + {0x821c,0xab}, + {0x821d,0x0d}, + {0x821e,0xaa}, + {0x821f,0x0c}, + {0x8220,0xa9}, + {0x8221,0x0b}, + {0x8222,0xa8}, + {0x8223,0x0a}, + {0x8224,0x22}, + {0x8225,0x90}, + {0x8226,0x30}, + {0x8227,0x42}, + {0x8228,0xe0}, + {0x8229,0xf5}, + {0x822a,0x22}, + {0x822b,0x75}, + {0x822c,0x51}, + {0x822d,0x0a}, + {0x822e,0x22}, + {0x822f,0xf5}, + {0x8230,0x82}, + {0x8231,0xe4}, + {0x8232,0x3a}, + {0x8233,0xf5}, + {0x8234,0x83}, + {0x8235,0x02}, + {0x8236,0x09}, + {0x8237,0xe5}, + {0x8238,0x8f}, + {0x8239,0x0a}, + {0x823a,0x74}, + {0x823b,0x4a}, + {0x823c,0x2f}, + {0x823d,0xf8}, + {0x823e,0xe6}, + {0x823f,0x22}, + {0x8240,0xc2}, + {0x8241,0x07}, + {0x8242,0xc2}, + {0x8243,0x06}, + {0x8244,0xc2}, + {0x8245,0x02}, + {0x8246,0xc2}, + {0x8247,0x01}, + {0x8248,0xc2}, + {0x8249,0x00}, + {0x824a,0xc2}, + {0x824b,0x03}, + {0x824c,0xd2}, + {0x824d,0x04}, + {0x824e,0x22}, + {0x824f,0xf5}, + {0x8250,0x82}, + {0x8251,0xe4}, + {0x8252,0x35}, + {0x8253,0x48}, + {0x8254,0xf5}, + {0x8255,0x83}, + {0x8256,0xe4}, + {0x8257,0x22}, + {0x8258,0x8e}, + {0x8259,0x67}, + {0x825a,0x8f}, + {0x825b,0x68}, + {0x825c,0x85}, + {0x825d,0x68}, + {0x825e,0x64}, + {0x825f,0xe5}, + {0x8260,0x68}, + {0x8261,0xae}, + {0x8262,0x67}, + {0x8263,0x78}, + {0x8264,0x06}, + {0x8265,0x22}, + {0x8266,0xe5}, + {0x8267,0x16}, + {0x8268,0x25}, + {0x8269,0xe0}, + {0x826a,0x25}, + {0x826b,0xe0}, + {0x826c,0x22}, + {0x826d,0x12}, + {0x826e,0x09}, + {0x826f,0x2d}, + {0x8270,0x8f}, + {0x8271,0x68}, + {0x8272,0x8e}, + {0x8273,0x67}, + {0x8274,0x8d}, + {0x8275,0x66}, + {0x8276,0x8c}, + {0x8277,0x65}, + {0x8278,0x22}, + {0x8279,0xe4}, + {0x827a,0x85}, + {0x827b,0x0f}, + {0x827c,0x0d}, + {0x827d,0x85}, + {0x827e,0x0e}, + {0x827f,0x0c}, + {0x8280,0xf5}, + {0x8281,0x0b}, + {0x8282,0xf5}, + {0x8283,0x0a}, + {0x8284,0x22}, + {0x8285,0x90}, + {0x8286,0x13}, + {0x8287,0x70}, + {0x8288,0xe4}, + {0x8289,0x93}, + {0x828a,0xff}, + {0x828b,0x90}, + {0x828c,0x30}, + {0x828d,0x0a}, + {0x828e,0xe0}, + {0x828f,0x22}, + {0x8290,0xc2}, + {0x8291,0x02}, + {0x8292,0xc2}, + {0x8293,0x01}, + {0x8294,0xd2}, + {0x8295,0x00}, + {0x8296,0xc2}, + {0x8297,0x03}, + {0x8298,0xc2}, + {0x8299,0x04}, + {0x829a,0x22}, + {0x829b,0x85}, + {0x829c,0x0e}, + {0x829d,0x64}, + {0x829e,0xe5}, + {0x829f,0x0e}, + {0x82a0,0xae}, + {0x82a1,0x0d}, + {0x82a2,0x78}, + {0x82a3,0x06}, + {0x82a4,0x22}, + {0x82a5,0xd2}, + {0x82a6,0x02}, + {0x82a7,0xd2}, + {0x82a8,0x01}, + {0x82a9,0xc2}, + {0x82aa,0x00}, + {0x82ab,0x22}, + {0x82ac,0x74}, + {0x82ad,0x4a}, + {0x82ae,0x25}, + {0x82af,0x0a}, + {0x82b0,0xf8}, + {0x82b1,0xe6}, + {0x82b2,0x22}, + {0x82b3,0xd3}, + {0x82b4,0xe5}, + {0x82b5,0x0b}, + {0x82b6,0x94}, + {0x82b7,0xff}, + {0x82b8,0xe5}, + {0x82b9,0x0a}, + {0x82ba,0x94}, + {0x82bb,0x00}, + {0x82bc,0x22}, + {0x82bd,0xd3}, + {0x82be,0xe5}, + {0x82bf,0x68}, + {0x82c0,0x94}, + {0x82c1,0xff}, + {0x82c2,0xe5}, + {0x82c3,0x67}, + {0x82c4,0x94}, + {0x82c5,0x00}, + {0x82c6,0x22}, + {0x82c7,0x30}, + {0x82c8,0x18}, + {0x82c9,0x4d}, + {0x82ca,0x20}, + {0x82cb,0x19}, + {0x82cc,0x4a}, + {0x82cd,0x75}, + {0x82ce,0x0a}, + {0x82cf,0x02}, + {0x82d0,0x12}, + {0x82d1,0x02}, + {0x82d2,0xac}, + {0x82d3,0xff}, + {0x82d4,0xe5}, + {0x82d5,0x4a}, + {0x82d6,0xd3}, + {0x82d7,0x9f}, + {0x82d8,0x40}, + {0x82d9,0x04}, + {0x82da,0x7f}, + {0x82db,0x00}, + {0x82dc,0x80}, + {0x82dd,0x02}, + {0x82de,0xaf}, + {0x82df,0x0a}, + {0x82e0,0x12}, + {0x82e1,0x02}, + {0x82e2,0x38}, + {0x82e3,0xff}, + {0x82e4,0xe5}, + {0x82e5,0x4b}, + {0x82e6,0xd3}, + {0x82e7,0x9f}, + {0x82e8,0x40}, + {0x82e9,0x04}, + {0x82ea,0x7f}, + {0x82eb,0x01}, + {0x82ec,0x80}, + {0x82ed,0x02}, + {0x82ee,0xaf}, + {0x82ef,0x0a}, + {0x82f0,0x12}, + {0x82f1,0x02}, + {0x82f2,0x38}, + {0x82f3,0xff}, + {0x82f4,0xe5}, + {0x82f5,0x4d}, + {0x82f6,0xd3}, + {0x82f7,0x9f}, + {0x82f8,0x40}, + {0x82f9,0x04}, + {0x82fa,0x7f}, + {0x82fb,0x03}, + {0x82fc,0x80}, + {0x82fd,0x02}, + {0x82fe,0xaf}, + {0x82ff,0x0a}, + {0x8300,0x12}, + {0x8301,0x02}, + {0x8302,0x38}, + {0x8303,0xff}, + {0x8304,0xe5}, + {0x8305,0x4e}, + {0x8306,0xd3}, + {0x8307,0x9f}, + {0x8308,0x40}, + {0x8309,0x04}, + {0x830a,0x7f}, + {0x830b,0x04}, + {0x830c,0x80}, + {0x830d,0x02}, + {0x830e,0xaf}, + {0x830f,0x0a}, + {0x8310,0x12}, + {0x8311,0x02}, + {0x8312,0x38}, + {0x8313,0xf5}, + {0x8314,0x0b}, + {0x8315,0x80}, + {0x8316,0x06}, + {0x8317,0x85}, + {0x8318,0x78}, + {0x8319,0x0a}, + {0x831a,0x85}, + {0x831b,0x4f}, + {0x831c,0x0b}, + {0x831d,0x7f}, + {0x831e,0x01}, + {0x831f,0xe4}, + {0x8320,0xfe}, + {0x8321,0x12}, + {0x8322,0x02}, + {0x8323,0xac}, + {0x8324,0xfd}, + {0x8325,0xe5}, + {0x8326,0x0b}, + {0x8327,0xc3}, + {0x8328,0x9d}, + {0x8329,0x50}, + {0x832a,0x04}, + {0x832b,0x7d}, + {0x832c,0x01}, + {0x832d,0x80}, + {0x832e,0x02}, + {0x832f,0x7d}, + {0x8330,0xff}, + {0x8331,0xac}, + {0x8332,0x0b}, + {0x8333,0xe5}, + {0x8334,0x4e}, + {0x8335,0xb5}, + {0x8336,0x0b}, + {0x8337,0x03}, + {0x8338,0xd3}, + {0x8339,0x80}, + {0x833a,0x01}, + {0x833b,0xc3}, + {0x833c,0x92}, + {0x833d,0x1f}, + {0x833e,0xe5}, + {0x833f,0x4d}, + {0x8340,0xb5}, + {0x8341,0x0b}, + {0x8342,0x03}, + {0x8343,0xd3}, + {0x8344,0x80}, + {0x8345,0x01}, + {0x8346,0xc3}, + {0x8347,0x92}, + {0x8348,0x1e}, + {0x8349,0xe5}, + {0x834a,0x4c}, + {0x834b,0xb5}, + {0x834c,0x0b}, + {0x834d,0x03}, + {0x834e,0xd3}, + {0x834f,0x80}, + {0x8350,0x01}, + {0x8351,0xc3}, + {0x8352,0x92}, + {0x8353,0x1d}, + {0x8354,0xe5}, + {0x8355,0x4b}, + {0x8356,0xb5}, + {0x8357,0x0b}, + {0x8358,0x03}, + {0x8359,0xd3}, + {0x835a,0x80}, + {0x835b,0x01}, + {0x835c,0xc3}, + {0x835d,0x92}, + {0x835e,0x1c}, + {0x835f,0xe5}, + {0x8360,0x4a}, + {0x8361,0xb5}, + {0x8362,0x0b}, + {0x8363,0x03}, + {0x8364,0xd3}, + {0x8365,0x80}, + {0x8366,0x01}, + {0x8367,0xc3}, + {0x8368,0x92}, + {0x8369,0x1b}, + {0x836a,0xe5}, + {0x836b,0x30}, + {0x836c,0xd3}, + {0x836d,0x94}, + {0x836e,0x00}, + {0x836f,0x40}, + {0x8370,0x04}, + {0x8371,0xa2}, + {0x8372,0x1f}, + {0x8373,0x80}, + {0x8374,0x01}, + {0x8375,0xc3}, + {0x8376,0x92}, + {0x8377,0x1f}, + {0x8378,0xe5}, + {0x8379,0x2f}, + {0x837a,0xd3}, + {0x837b,0x94}, + {0x837c,0x00}, + {0x837d,0x40}, + {0x837e,0x04}, + {0x837f,0xa2}, + {0x8380,0x1e}, + {0x8381,0x80}, + {0x8382,0x01}, + {0x8383,0xc3}, + {0x8384,0x92}, + {0x8385,0x1e}, + {0x8386,0xe5}, + {0x8387,0x2e}, + {0x8388,0xd3}, + {0x8389,0x94}, + {0x838a,0x00}, + {0x838b,0x40}, + {0x838c,0x04}, + {0x838d,0xa2}, + {0x838e,0x1d}, + {0x838f,0x80}, + {0x8390,0x01}, + {0x8391,0xc3}, + {0x8392,0x92}, + {0x8393,0x1d}, + {0x8394,0xe5}, + {0x8395,0x2d}, + {0x8396,0xd3}, + {0x8397,0x94}, + {0x8398,0x00}, + {0x8399,0x40}, + {0x839a,0x04}, + {0x839b,0xa2}, + {0x839c,0x1c}, + {0x839d,0x80}, + {0x839e,0x01}, + {0x839f,0xc3}, + {0x83a0,0x92}, + {0x83a1,0x1c}, + {0x83a2,0xe5}, + {0x83a3,0x2c}, + {0x83a4,0xd3}, + {0x83a5,0x94}, + {0x83a6,0x00}, + {0x83a7,0x40}, + {0x83a8,0x04}, + {0x83a9,0xa2}, + {0x83aa,0x1b}, + {0x83ab,0x80}, + {0x83ac,0x01}, + {0x83ad,0xc3}, + {0x83ae,0x92}, + {0x83af,0x1b}, + {0x83b0,0xe5}, + {0x83b1,0x23}, + {0x83b2,0x54}, + {0x83b3,0xf8}, + {0x83b4,0x70}, + {0x83b5,0x5b}, + {0x83b6,0xbf}, + {0x83b7,0x01}, + {0x83b8,0x08}, + {0x83b9,0xed}, + {0x83ba,0xf4}, + {0x83bb,0x04}, + {0x83bc,0xfd}, + {0x83bd,0x7f}, + {0x83be,0x02}, + {0x83bf,0x80}, + {0x83c0,0x06}, + {0x83c1,0xbf}, + {0x83c2,0x02}, + {0x83c3,0x02}, + {0x83c4,0x7f}, + {0x83c5,0x01}, + {0x83c6,0x0e}, + {0x83c7,0xd3}, + {0x83c8,0xed}, + {0x83c9,0x64}, + {0x83ca,0x80}, + {0x83cb,0x94}, + {0x83cc,0x80}, + {0x83cd,0x40}, + {0x83ce,0x18}, + {0x83cf,0xec}, + {0x83d0,0x2e}, + {0x83d1,0xf5}, + {0x83d2,0x0b}, + {0x83d3,0xd3}, + {0x83d4,0x95}, + {0x83d5,0x7b}, + {0x83d6,0x40}, + {0x83d7,0x2c}, + {0x83d8,0x7d}, + {0x83d9,0xff}, + {0x83da,0xef}, + {0x83db,0x60}, + {0x83dc,0x04}, + {0x83dd,0x7b}, + {0x83de,0x00}, + {0x83df,0x80}, + {0x83e0,0x02}, + {0x83e1,0x7b}, + {0x83e2,0x03}, + {0x83e3,0xaf}, + {0x83e4,0x03}, + {0x83e5,0x80}, + {0x83e6,0x18}, + {0x83e7,0xec}, + {0x83e8,0xc3}, + {0x83e9,0x9e}, + {0x83ea,0x50}, + {0x83eb,0x13}, + {0x83ec,0x7d}, + {0x83ed,0x01}, + {0x83ee,0xef}, + {0x83ef,0x60}, + {0x83f0,0x04}, + {0x83f1,0x7b}, + {0x83f2,0x00}, + {0x83f3,0x80}, + {0x83f4,0x02}, + {0x83f5,0x7b}, + {0x83f6,0x03}, + {0x83f7,0xaf}, + {0x83f8,0x03}, + {0x83f9,0xec}, + {0x83fa,0x2e}, + {0x83fb,0xf5}, + {0x83fc,0x0b}, + {0x83fd,0x80}, + {0x83fe,0x05}, + {0x83ff,0xc3}, + {0x8400,0xec}, + {0x8401,0x9e}, + {0x8402,0xf5}, + {0x8403,0x0b}, + {0x8404,0xef}, + {0x8405,0x64}, + {0x8406,0x03}, + {0x8407,0x60}, + {0x8408,0x03}, + {0x8409,0x02}, + {0x840a,0x03}, + {0x840b,0x33}, + {0x840c,0x12}, + {0x840d,0x02}, + {0x840e,0xac}, + {0x840f,0xf5}, + {0x8410,0x0b}, + {0x8411,0x12}, + {0x8412,0x01}, + {0x8413,0xde}, + {0x8414,0xe5}, + {0x8415,0x4e}, + {0x8416,0xb5}, + {0x8417,0x07}, + {0x8418,0x07}, + {0x8419,0xe4}, + {0x841a,0xb5}, + {0x841b,0x06}, + {0x841c,0x03}, + {0x841d,0xd3}, + {0x841e,0x80}, + {0x841f,0x02}, + {0x8420,0xa2}, + {0x8421,0x1f}, + {0x8422,0x92}, + {0x8423,0x1f}, + {0x8424,0xe5}, + {0x8425,0x4d}, + {0x8426,0xb5}, + {0x8427,0x07}, + {0x8428,0x07}, + {0x8429,0xe4}, + {0x842a,0xb5}, + {0x842b,0x06}, + {0x842c,0x03}, + {0x842d,0xd3}, + {0x842e,0x80}, + {0x842f,0x02}, + {0x8430,0xa2}, + {0x8431,0x1e}, + {0x8432,0x92}, + {0x8433,0x1e}, + {0x8434,0x12}, + {0x8435,0x01}, + {0x8436,0xde}, + {0x8437,0xe5}, + {0x8438,0x4c}, + {0x8439,0xb5}, + {0x843a,0x07}, + {0x843b,0x07}, + {0x843c,0xe4}, + {0x843d,0xb5}, + {0x843e,0x06}, + {0x843f,0x03}, + {0x8440,0xd3}, + {0x8441,0x80}, + {0x8442,0x02}, + {0x8443,0xa2}, + {0x8444,0x1d}, + {0x8445,0x92}, + {0x8446,0x1d}, + {0x8447,0xe5}, + {0x8448,0x4b}, + {0x8449,0xb5}, + {0x844a,0x07}, + {0x844b,0x07}, + {0x844c,0xe4}, + {0x844d,0xb5}, + {0x844e,0x06}, + {0x844f,0x03}, + {0x8450,0xd3}, + {0x8451,0x80}, + {0x8452,0x02}, + {0x8453,0xa2}, + {0x8454,0x1c}, + {0x8455,0x92}, + {0x8456,0x1c}, + {0x8457,0x12}, + {0x8458,0x01}, + {0x8459,0xde}, + {0x845a,0xe5}, + {0x845b,0x4a}, + {0x845c,0xb5}, + {0x845d,0x07}, + {0x845e,0x07}, + {0x845f,0xe4}, + {0x8460,0xb5}, + {0x8461,0x06}, + {0x8462,0x03}, + {0x8463,0xd3}, + {0x8464,0x80}, + {0x8465,0x02}, + {0x8466,0xa2}, + {0x8467,0x1b}, + {0x8468,0x92}, + {0x8469,0x1b}, + {0x846a,0xe5}, + {0x846b,0x4e}, + {0x846c,0x12}, + {0x846d,0x01}, + {0x846e,0xe0}, + {0x846f,0xad}, + {0x8470,0x0b}, + {0x8471,0x7c}, + {0x8472,0x00}, + {0x8473,0xef}, + {0x8474,0xb5}, + {0x8475,0x05}, + {0x8476,0x07}, + {0x8477,0xec}, + {0x8478,0xb5}, + {0x8479,0x06}, + {0x847a,0x03}, + {0x847b,0xd3}, + {0x847c,0x80}, + {0x847d,0x02}, + {0x847e,0xa2}, + {0x847f,0x1f}, + {0x8480,0x92}, + {0x8481,0x1f}, + {0x8482,0xe5}, + {0x8483,0x4d}, + {0x8484,0x12}, + {0x8485,0x01}, + {0x8486,0xe0}, + {0x8487,0xef}, + {0x8488,0xb5}, + {0x8489,0x05}, + {0x848a,0x07}, + {0x848b,0xee}, + {0x848c,0xb5}, + {0x848d,0x04}, + {0x848e,0x03}, + {0x848f,0xd3}, + {0x8490,0x80}, + {0x8491,0x02}, + {0x8492,0xa2}, + {0x8493,0x1e}, + {0x8494,0x92}, + {0x8495,0x1e}, + {0x8496,0xe5}, + {0x8497,0x4c}, + {0x8498,0x12}, + {0x8499,0x01}, + {0x849a,0xe0}, + {0x849b,0xad}, + {0x849c,0x0b}, + {0x849d,0x7c}, + {0x849e,0x00}, + {0x849f,0xef}, + {0x84a0,0xb5}, + {0x84a1,0x05}, + {0x84a2,0x07}, + {0x84a3,0xec}, + {0x84a4,0xb5}, + {0x84a5,0x06}, + {0x84a6,0x03}, + {0x84a7,0xd3}, + {0x84a8,0x80}, + {0x84a9,0x02}, + {0x84aa,0xa2}, + {0x84ab,0x1d}, + {0x84ac,0x92}, + {0x84ad,0x1d}, + {0x84ae,0xe5}, + {0x84af,0x4b}, + {0x84b0,0x12}, + {0x84b1,0x01}, + {0x84b2,0xe0}, + {0x84b3,0xef}, + {0x84b4,0xb5}, + {0x84b5,0x05}, + {0x84b6,0x07}, + {0x84b7,0xee}, + {0x84b8,0xb5}, + {0x84b9,0x04}, + {0x84ba,0x03}, + {0x84bb,0xd3}, + {0x84bc,0x80}, + {0x84bd,0x02}, + {0x84be,0xa2}, + {0x84bf,0x1c}, + {0x84c0,0x92}, + {0x84c1,0x1c}, + {0x84c2,0xe5}, + {0x84c3,0x4a}, + {0x84c4,0x12}, + {0x84c5,0x01}, + {0x84c6,0xe0}, + {0x84c7,0x7c}, + {0x84c8,0x00}, + {0x84c9,0xef}, + {0x84ca,0xb5}, + {0x84cb,0x0b}, + {0x84cc,0x07}, + {0x84cd,0xec}, + {0x84ce,0xb5}, + {0x84cf,0x06}, + {0x84d0,0x03}, + {0x84d1,0xd3}, + {0x84d2,0x80}, + {0x84d3,0x02}, + {0x84d4,0xa2}, + {0x84d5,0x1b}, + {0x84d6,0x92}, + {0x84d7,0x1b}, + {0x84d8,0xe5}, + {0x84d9,0x30}, + {0x84da,0xd3}, + {0x84db,0x94}, + {0x84dc,0x00}, + {0x84dd,0x40}, + {0x84de,0x04}, + {0x84df,0xa2}, + {0x84e0,0x1f}, + {0x84e1,0x80}, + {0x84e2,0x01}, + {0x84e3,0xc3}, + {0x84e4,0x92}, + {0x84e5,0x1f}, + {0x84e6,0xe5}, + {0x84e7,0x2f}, + {0x84e8,0xd3}, + {0x84e9,0x94}, + {0x84ea,0x00}, + {0x84eb,0x40}, + {0x84ec,0x04}, + {0x84ed,0xa2}, + {0x84ee,0x1e}, + {0x84ef,0x80}, + {0x84f0,0x01}, + {0x84f1,0xc3}, + {0x84f2,0x92}, + {0x84f3,0x1e}, + {0x84f4,0xe5}, + {0x84f5,0x2e}, + {0x84f6,0xd3}, + {0x84f7,0x94}, + {0x84f8,0x00}, + {0x84f9,0x40}, + {0x84fa,0x04}, + {0x84fb,0xa2}, + {0x84fc,0x1d}, + {0x84fd,0x80}, + {0x84fe,0x01}, + {0x84ff,0xc3}, + {0x8500,0x92}, + {0x8501,0x1d}, + {0x8502,0xe5}, + {0x8503,0x2d}, + {0x8504,0xd3}, + {0x8505,0x94}, + {0x8506,0x00}, + {0x8507,0x40}, + {0x8508,0x04}, + {0x8509,0xa2}, + {0x850a,0x1c}, + {0x850b,0x80}, + {0x850c,0x01}, + {0x850d,0xc3}, + {0x850e,0x92}, + {0x850f,0x1c}, + {0x8510,0xe5}, + {0x8511,0x2c}, + {0x8512,0xd3}, + {0x8513,0x94}, + {0x8514,0x00}, + {0x8515,0x40}, + {0x8516,0x04}, + {0x8517,0xa2}, + {0x8518,0x1b}, + {0x8519,0x80}, + {0x851a,0x01}, + {0x851b,0xc3}, + {0x851c,0x92}, + {0x851d,0x1b}, + {0x851e,0x85}, + {0x851f,0x0a}, + {0x8520,0x78}, + {0x8521,0xe5}, + {0x8522,0x7c}, + {0x8523,0xb5}, + {0x8524,0x0b}, + {0x8525,0x03}, + {0x8526,0x02}, + {0x8527,0x16}, + {0x8528,0x5f}, + {0x8529,0x85}, + {0x852a,0x0b}, + {0x852b,0x0c}, + {0x852c,0x12}, + {0x852d,0x0f}, + {0x852e,0x52}, + {0x852f,0xd2}, + {0x8530,0x02}, + {0x8531,0xc2}, + {0x8532,0x01}, + {0x8533,0xd2}, + {0x8534,0x00}, + {0x8535,0x75}, + {0x8536,0x31}, + {0x8537,0x03}, + {0x8538,0x22}, + {0x8539,0xe5}, + {0x853a,0x7d}, + {0x853b,0x24}, + {0x853c,0xfe}, + {0x853d,0x60}, + {0x853e,0x27}, + {0x853f,0x14}, + {0x8540,0x60}, + {0x8541,0x31}, + {0x8542,0x24}, + {0x8543,0xf8}, + {0x8544,0x60}, + {0x8545,0x3a}, + {0x8546,0x14}, + {0x8547,0x60}, + {0x8548,0x4b}, + {0x8549,0x14}, + {0x854a,0x60}, + {0x854b,0x59}, + {0x854c,0x14}, + {0x854d,0x60}, + {0x854e,0x6a}, + {0x854f,0x24}, + {0x8550,0xfd}, + {0x8551,0x70}, + {0x8552,0x03}, + {0x8553,0x02}, + {0x8554,0x05}, + {0x8555,0xee}, + {0x8556,0x24}, + {0x8557,0x10}, + {0x8558,0x60}, + {0x8559,0x03}, + {0x855a,0x02}, + {0x855b,0x06}, + {0x855c,0xe9}, + {0x855d,0xe4}, + {0x855e,0xf5}, + {0x855f,0x0a}, + {0x8560,0x12}, + {0x8561,0x12}, + {0x8562,0x48}, + {0x8563,0x02}, + {0x8564,0x06}, + {0x8565,0xd2}, + {0x8566,0x75}, + {0x8567,0x0a}, + {0x8568,0x01}, + {0x8569,0x12}, + {0x856a,0x06}, + {0x856b,0xea}, + {0x856c,0xc2}, + {0x856d,0x3c}, + {0x856e,0xd2}, + {0x856f,0x3b}, + {0x8570,0x02}, + {0x8571,0x06}, + {0x8572,0xe3}, + {0x8573,0x75}, + {0x8574,0x0a}, + {0x8575,0x02}, + {0x8576,0x12}, + {0x8577,0x06}, + {0x8578,0xea}, + {0x8579,0xd2}, + {0x857a,0x3c}, + {0x857b,0xc2}, + {0x857c,0x3b}, + {0x857d,0x02}, + {0x857e,0x06}, + {0x857f,0xe3}, + {0x8580,0x30}, + {0x8581,0x38}, + {0x8582,0x0c}, + {0x8583,0x20}, + {0x8584,0x3c}, + {0x8585,0x03}, + {0x8586,0x30}, + {0x8587,0x3b}, + {0x8588,0x06}, + {0x8589,0xe4}, + {0x858a,0xf5}, + {0x858b,0x0a}, + {0x858c,0x12}, + {0x858d,0x14}, + {0x858e,0x78}, + {0x858f,0xd2}, + {0x8590,0x18}, + {0x8591,0xc2}, + {0x8592,0x19}, + {0x8593,0x22}, + {0x8594,0x30}, + {0x8595,0x38}, + {0x8596,0x09}, + {0x8597,0x20}, + {0x8598,0x3c}, + {0x8599,0x03}, + {0x859a,0x30}, + {0x859b,0x3b}, + {0x859c,0x03}, + {0x859d,0x12}, + {0x859e,0x06}, + {0x859f,0xfb}, + {0x85a0,0xd2}, + {0x85a1,0x18}, + {0x85a2,0xd2}, + {0x85a3,0x19}, + {0x85a4,0x22}, + {0x85a5,0x30}, + {0x85a6,0x38}, + {0x85a7,0x0c}, + {0x85a8,0x20}, + {0x85a9,0x3c}, + {0x85aa,0x03}, + {0x85ab,0x30}, + {0x85ac,0x3b}, + {0x85ad,0x06}, + {0x85ae,0x75}, + {0x85af,0x0a}, + {0x85b0,0x02}, + {0x85b1,0x12}, + {0x85b2,0x14}, + {0x85b3,0x78}, + {0x85b4,0xc2}, + {0x85b5,0x18}, + {0x85b6,0xd2}, + {0x85b7,0x19}, + {0x85b8,0x22}, + {0x85b9,0x20}, + {0x85ba,0x3c}, + {0x85bb,0x06}, + {0x85bc,0x20}, + {0x85bd,0x3b}, + {0x85be,0x03}, + {0x85bf,0x02}, + {0x85c0,0x06}, + {0x85c1,0xe9}, + {0x85c2,0xe5}, + {0x85c3,0x78}, + {0x85c4,0xd3}, + {0x85c5,0x94}, + {0x85c6,0x03}, + {0x85c7,0x40}, + {0x85c8,0x04}, + {0x85c9,0x7f}, + {0x85ca,0x00}, + {0x85cb,0x80}, + {0x85cc,0x04}, + {0x85cd,0xe5}, + {0x85ce,0x78}, + {0x85cf,0x04}, + {0x85d0,0xff}, + {0x85d1,0x8f}, + {0x85d2,0x78}, + {0x85d3,0x30}, + {0x85d4,0x18}, + {0x85d5,0x06}, + {0x85d6,0x30}, + {0x85d7,0x19}, + {0x85d8,0x03}, + {0x85d9,0x12}, + {0x85da,0x06}, + {0x85db,0xfb}, + {0x85dc,0x30}, + {0x85dd,0x18}, + {0x85de,0x03}, + {0x85df,0x02}, + {0x85e0,0x06}, + {0x85e1,0xe9}, + {0x85e2,0x20}, + {0x85e3,0x19}, + {0x85e4,0x03}, + {0x85e5,0x02}, + {0x85e6,0x06}, + {0x85e7,0xe9}, + {0x85e8,0x75}, + {0x85e9,0x0a}, + {0x85ea,0x02}, + {0x85eb,0x02}, + {0x85ec,0x14}, + {0x85ed,0x78}, + {0x85ee,0xe5}, + {0x85ef,0x67}, + {0x85f0,0xd3}, + {0x85f1,0x94}, + {0x85f2,0x38}, + {0x85f3,0x40}, + {0x85f4,0x04}, + {0x85f5,0x7f}, + {0x85f6,0x34}, + {0x85f7,0x80}, + {0x85f8,0x02}, + {0x85f9,0xaf}, + {0x85fa,0x67}, + {0x85fb,0x8f}, + {0x85fc,0x67}, + {0x85fd,0xe5}, + {0x85fe,0x67}, + {0x85ff,0xc3}, + {0x8600,0x94}, + {0x8601,0x08}, + {0x8602,0x50}, + {0x8603,0x04}, + {0x8604,0x7f}, + {0x8605,0x08}, + {0x8606,0x80}, + {0x8607,0x02}, + {0x8608,0xaf}, + {0x8609,0x67}, + {0x860a,0x8f}, + {0x860b,0x67}, + {0x860c,0xe5}, + {0x860d,0x68}, + {0x860e,0xd3}, + {0x860f,0x94}, + {0x8610,0x2a}, + {0x8611,0x40}, + {0x8612,0x04}, + {0x8613,0x7f}, + {0x8614,0x2a}, + {0x8615,0x80}, + {0x8616,0x02}, + {0x8617,0xaf}, + {0x8618,0x68}, + {0x8619,0x8f}, + {0x861a,0x68}, + {0x861b,0xe5}, + {0x861c,0x68}, + {0x861d,0xc3}, + {0x861e,0x94}, + {0x861f,0x06}, + {0x8620,0x50}, + {0x8621,0x04}, + {0x8622,0x7f}, + {0x8623,0x06}, + {0x8624,0x80}, + {0x8625,0x02}, + {0x8626,0xaf}, + {0x8627,0x68}, + {0x8628,0x8f}, + {0x8629,0x68}, + {0x862a,0xaf}, + {0x862b,0x67}, + {0x862c,0xef}, + {0x862d,0x24}, + {0x862e,0xf8}, + {0x862f,0xff}, + {0x8630,0xe4}, + {0x8631,0x34}, + {0x8632,0xff}, + {0x8633,0xfe}, + {0x8634,0xe4}, + {0x8635,0x8f}, + {0x8636,0x3f}, + {0x8637,0x8e}, + {0x8638,0x3e}, + {0x8639,0xf5}, + {0x863a,0x3d}, + {0x863b,0xf5}, + {0x863c,0x3c}, + {0x863d,0xac}, + {0x863e,0x3c}, + {0x863f,0x12}, + {0x8640,0x01}, + {0x8641,0x90}, + {0x8642,0xaf}, + {0x8643,0x68}, + {0x8644,0xef}, + {0x8645,0x24}, + {0x8646,0xfa}, + {0x8647,0xff}, + {0x8648,0xe4}, + {0x8649,0x34}, + {0x864a,0xff}, + {0x864b,0x12}, + {0x864c,0x01}, + {0x864d,0x73}, + {0x864e,0xaf}, + {0x864f,0x67}, + {0x8650,0xef}, + {0x8651,0x24}, + {0x8652,0x08}, + {0x8653,0xff}, + {0x8654,0xe4}, + {0x8655,0x33}, + {0x8656,0x12}, + {0x8657,0x01}, + {0x8658,0x73}, + {0x8659,0xaf}, + {0x865a,0x68}, + {0x865b,0xef}, + {0x865c,0x24}, + {0x865d,0x06}, + {0x865e,0xff}, + {0x865f,0xe4}, + {0x8660,0x33}, + {0x8661,0xfe}, + {0x8662,0xe4}, + {0x8663,0xfc}, + {0x8664,0xfd}, + {0x8665,0xe5}, + {0x8666,0x3f}, + {0x8667,0x2f}, + {0x8668,0xf5}, + {0x8669,0x3f}, + {0x866a,0xe5}, + {0x866b,0x3e}, + {0x866c,0x3e}, + {0x866d,0xf5}, + {0x866e,0x3e}, + {0x866f,0xed}, + {0x8670,0x35}, + {0x8671,0x3d}, + {0x8672,0xf5}, + {0x8673,0x3d}, + {0x8674,0xec}, + {0x8675,0x35}, + {0x8676,0x3c}, + {0x8677,0xf5}, + {0x8678,0x3c}, + {0x8679,0xe4}, + {0x867a,0x25}, + {0x867b,0x3f}, + {0x867c,0xf5}, + {0x867d,0x37}, + {0x867e,0xe4}, + {0x867f,0x35}, + {0x8680,0x3e}, + {0x8681,0xf5}, + {0x8682,0x36}, + {0x8683,0xe4}, + {0x8684,0x35}, + {0x8685,0x3d}, + {0x8686,0xf5}, + {0x8687,0x35}, + {0x8688,0xe5}, + {0x8689,0x3c}, + {0x868a,0x34}, + {0x868b,0x08}, + {0x868c,0xf5}, + {0x868d,0x34}, + {0x868e,0xe4}, + {0x868f,0x25}, + {0x8690,0x3f}, + {0x8691,0xf5}, + {0x8692,0x3b}, + {0x8693,0xe4}, + {0x8694,0x35}, + {0x8695,0x3e}, + {0x8696,0xf5}, + {0x8697,0x3a}, + {0x8698,0xe5}, + {0x8699,0x3d}, + {0x869a,0x34}, + {0x869b,0x06}, + {0x869c,0xf5}, + {0x869d,0x39}, + {0x869e,0xe4}, + {0x869f,0x35}, + {0x86a0,0x3c}, + {0x86a1,0xf5}, + {0x86a2,0x38}, + {0x86a3,0xe5}, + {0x86a4,0x3f}, + {0x86a5,0x24}, + {0x86a6,0xfa}, + {0x86a7,0xf5}, + {0x86a8,0x43}, + {0x86a9,0xe5}, + {0x86aa,0x3e}, + {0x86ab,0x34}, + {0x86ac,0xff}, + {0x86ad,0xf5}, + {0x86ae,0x42}, + {0x86af,0xe5}, + {0x86b0,0x3d}, + {0x86b1,0x34}, + {0x86b2,0xff}, + {0x86b3,0xf5}, + {0x86b4,0x41}, + {0x86b5,0xe5}, + {0x86b6,0x3c}, + {0x86b7,0x34}, + {0x86b8,0xff}, + {0x86b9,0xf5}, + {0x86ba,0x40}, + {0x86bb,0xe4}, + {0x86bc,0x25}, + {0x86bd,0x3f}, + {0x86be,0xf5}, + {0x86bf,0x47}, + {0x86c0,0xe5}, + {0x86c1,0x3e}, + {0x86c2,0x34}, + {0x86c3,0xf8}, + {0x86c4,0xf5}, + {0x86c5,0x46}, + {0x86c6,0xe5}, + {0x86c7,0x3d}, + {0x86c8,0x34}, + {0x86c9,0xff}, + {0x86ca,0xf5}, + {0x86cb,0x45}, + {0x86cc,0xe5}, + {0x86cd,0x3c}, + {0x86ce,0x34}, + {0x86cf,0xff}, + {0x86d0,0xf5}, + {0x86d1,0x44}, + {0x86d2,0x75}, + {0x86d3,0x78}, + {0x86d4,0x02}, + {0x86d5,0x75}, + {0x86d6,0x0a}, + {0x86d7,0x01}, + {0x86d8,0x12}, + {0x86d9,0x14}, + {0x86da,0x78}, + {0x86db,0xd2}, + {0x86dc,0x18}, + {0x86dd,0xd2}, + {0x86de,0x19}, + {0x86df,0xc2}, + {0x86e0,0x3c}, + {0x86e1,0xc2}, + {0x86e2,0x3b}, + {0x86e3,0xd2}, + {0x86e4,0x1a}, + {0x86e5,0xd2}, + {0x86e6,0x38}, + {0x86e7,0xd2}, + {0x86e8,0x30}, + {0x86e9,0x22}, + {0x86ea,0x12}, + {0x86eb,0x12}, + {0x86ec,0x48}, + {0x86ed,0x75}, + {0x86ee,0x78}, + {0x86ef,0x02}, + {0x86f0,0xe4}, + {0x86f1,0xf5}, + {0x86f2,0x0a}, + {0x86f3,0x12}, + {0x86f4,0x14}, + {0x86f5,0x78}, + {0x86f6,0xd2}, + {0x86f7,0x18}, + {0x86f8,0xc2}, + {0x86f9,0x19}, + {0x86fa,0x22}, + {0x86fb,0x75}, + {0x86fc,0x0a}, + {0x86fd,0x01}, + {0x86fe,0x12}, + {0x86ff,0x14}, + {0x8700,0x78}, + {0x8701,0x22}, + {0x8702,0x90}, + {0x8703,0x38}, + {0x8704,0x04}, + {0x8705,0xe0}, + {0x8706,0xfe}, + {0x8707,0xa3}, + {0x8708,0xe0}, + {0x8709,0xfd}, + {0x870a,0xed}, + {0x870b,0xff}, + {0x870c,0xee}, + {0x870d,0x54}, + {0x870e,0x0f}, + {0x870f,0xf5}, + {0x8710,0x0e}, + {0x8711,0x8f}, + {0x8712,0x0f}, + {0x8713,0xa3}, + {0x8714,0xe0}, + {0x8715,0xfe}, + {0x8716,0xa3}, + {0x8717,0xe0}, + {0x8718,0xfd}, + {0x8719,0xed}, + {0x871a,0xff}, + {0x871b,0xee}, + {0x871c,0x54}, + {0x871d,0x07}, + {0x871e,0xf5}, + {0x871f,0x10}, + {0x8720,0x8f}, + {0x8721,0x11}, + {0x8722,0xe5}, + {0x8723,0x0e}, + {0x8724,0xc4}, + {0x8725,0xf8}, + {0x8726,0x54}, + {0x8727,0xf0}, + {0x8728,0xc8}, + {0x8729,0x68}, + {0x872a,0xf5}, + {0x872b,0x0e}, + {0x872c,0xe5}, + {0x872d,0x0f}, + {0x872e,0xc4}, + {0x872f,0x54}, + {0x8730,0x0f}, + {0x8731,0x48}, + {0x8732,0xf5}, + {0x8733,0x0f}, + {0x8734,0xe5}, + {0x8735,0x10}, + {0x8736,0xc4}, + {0x8737,0xf8}, + {0x8738,0x54}, + {0x8739,0xf0}, + {0x873a,0xc8}, + {0x873b,0x68}, + {0x873c,0xf5}, + {0x873d,0x10}, + {0x873e,0xe5}, + {0x873f,0x11}, + {0x8740,0xc4}, + {0x8741,0x54}, + {0x8742,0x0f}, + {0x8743,0x48}, + {0x8744,0xf5}, + {0x8745,0x11}, + {0x8746,0xe4}, + {0x8747,0xf5}, + {0x8748,0x17}, + {0x8749,0x75}, + {0x874a,0x16}, + {0x874b,0x04}, + {0x874c,0x12}, + {0x874d,0x02}, + {0x874e,0x66}, + {0x874f,0x24}, + {0x8750,0x34}, + {0x8751,0xf8}, + {0x8752,0xe6}, + {0x8753,0xf5}, + {0x8754,0x12}, + {0x8755,0x12}, + {0x8756,0x02}, + {0x8757,0x66}, + {0x8758,0x24}, + {0x8759,0x35}, + {0x875a,0xf8}, + {0x875b,0xe6}, + {0x875c,0xf5}, + {0x875d,0x14}, + {0x875e,0x12}, + {0x875f,0x02}, + {0x8760,0x66}, + {0x8761,0x24}, + {0x8762,0x36}, + {0x8763,0xf8}, + {0x8764,0xe6}, + {0x8765,0xf5}, + {0x8766,0x13}, + {0x8767,0x12}, + {0x8768,0x02}, + {0x8769,0x66}, + {0x876a,0x24}, + {0x876b,0x37}, + {0x876c,0xf8}, + {0x876d,0xe6}, + {0x876e,0xf5}, + {0x876f,0x15}, + {0x8770,0x12}, + {0x8771,0x02}, + {0x8772,0x79}, + {0x8773,0xaf}, + {0x8774,0x12}, + {0x8775,0x12}, + {0x8776,0x01}, + {0x8777,0x42}, + {0x8778,0x8f}, + {0x8779,0x12}, + {0x877a,0x12}, + {0x877b,0x02}, + {0x877c,0x79}, + {0x877d,0xaf}, + {0x877e,0x13}, + {0x877f,0x12}, + {0x8780,0x01}, + {0x8781,0x42}, + {0x8782,0x8f}, + {0x8783,0x13}, + {0x8784,0x12}, + {0x8785,0x02}, + {0x8786,0x11}, + {0x8787,0xaf}, + {0x8788,0x14}, + {0x8789,0xfc}, + {0x878a,0xfd}, + {0x878b,0xfe}, + {0x878c,0x12}, + {0x878d,0x08}, + {0x878e,0xa2}, + {0x878f,0x12}, + {0x8790,0x01}, + {0x8791,0x61}, + {0x8792,0x7b}, + {0x8793,0x30}, + {0x8794,0x12}, + {0x8795,0x01}, + {0x8796,0x5a}, + {0x8797,0x8f}, + {0x8798,0x14}, + {0x8799,0x12}, + {0x879a,0x02}, + {0x879b,0x11}, + {0x879c,0xaf}, + {0x879d,0x15}, + {0x879e,0xfc}, + {0x879f,0xfd}, + {0x87a0,0xfe}, + {0x87a1,0x12}, + {0x87a2,0x08}, + {0x87a3,0xa2}, + {0x87a4,0x12}, + {0x87a5,0x01}, + {0x87a6,0x61}, + {0x87a7,0xe4}, + {0x87a8,0x7b}, + {0x87a9,0x30}, + {0x87aa,0x12}, + {0x87ab,0x01}, + {0x87ac,0x5b}, + {0x87ad,0x8f}, + {0x87ae,0x15}, + {0x87af,0xc3}, + {0x87b0,0xe5}, + {0x87b1,0x13}, + {0x87b2,0x95}, + {0x87b3,0x12}, + {0x87b4,0xff}, + {0x87b5,0x0f}, + {0x87b6,0xef}, + {0x87b7,0xc3}, + {0x87b8,0x13}, + {0x87b9,0xff}, + {0x87ba,0xc3}, + {0x87bb,0x94}, + {0x87bc,0x04}, + {0x87bd,0x50}, + {0x87be,0x27}, + {0x87bf,0xe5}, + {0x87c0,0x12}, + {0x87c1,0x9f}, + {0x87c2,0x40}, + {0x87c3,0x06}, + {0x87c4,0xe5}, + {0x87c5,0x12}, + {0x87c6,0x9f}, + {0x87c7,0xfe}, + {0x87c8,0x80}, + {0x87c9,0x02}, + {0x87ca,0x7e}, + {0x87cb,0x00}, + {0x87cc,0x8e}, + {0x87cd,0x12}, + {0x87ce,0xef}, + {0x87cf,0xfd}, + {0x87d0,0xe5}, + {0x87d1,0x13}, + {0x87d2,0x2d}, + {0x87d3,0xfd}, + {0x87d4,0xe4}, + {0x87d5,0x33}, + {0x87d6,0xfc}, + {0x87d7,0xc3}, + {0x87d8,0xed}, + {0x87d9,0x95}, + {0x87da,0x0f}, + {0x87db,0xec}, + {0x87dc,0x95}, + {0x87dd,0x0e}, + {0x87de,0x50}, + {0x87df,0x02}, + {0x87e0,0x80}, + {0x87e1,0x02}, + {0x87e2,0xad}, + {0x87e3,0x0f}, + {0x87e4,0x8d}, + {0x87e5,0x13}, + {0x87e6,0xc3}, + {0x87e7,0xe5}, + {0x87e8,0x15}, + {0x87e9,0x95}, + {0x87ea,0x14}, + {0x87eb,0xff}, + {0x87ec,0xc3}, + {0x87ed,0x94}, + {0x87ee,0x04}, + {0x87ef,0x50}, + {0x87f0,0x29}, + {0x87f1,0xe5}, + {0x87f2,0x14}, + {0x87f3,0x9f}, + {0x87f4,0x40}, + {0x87f5,0x06}, + {0x87f6,0xe5}, + {0x87f7,0x14}, + {0x87f8,0x9f}, + {0x87f9,0xfe}, + {0x87fa,0x80}, + {0x87fb,0x02}, + {0x87fc,0x7e}, + {0x87fd,0x00}, + {0x87fe,0x8e}, + {0x87ff,0x14}, + {0x8800,0xef}, + {0x8801,0xfd}, + {0x8802,0xe5}, + {0x8803,0x15}, + {0x8804,0x2d}, + {0x8805,0xfd}, + {0x8806,0xe4}, + {0x8807,0x33}, + {0x8808,0xfc}, + {0x8809,0xc3}, + {0x880a,0xed}, + {0x880b,0x95}, + {0x880c,0x11}, + {0x880d,0xec}, + {0x880e,0x95}, + {0x880f,0x10}, + {0x8810,0x50}, + {0x8811,0x04}, + {0x8812,0xaf}, + {0x8813,0x05}, + {0x8814,0x80}, + {0x8815,0x02}, + {0x8816,0xaf}, + {0x8817,0x11}, + {0x8818,0x8f}, + {0x8819,0x15}, + {0x881a,0xe5}, + {0x881b,0x15}, + {0x881c,0xd3}, + {0x881d,0x95}, + {0x881e,0x17}, + {0x881f,0x40}, + {0x8820,0x04}, + {0x8821,0xaf}, + {0x8822,0x15}, + {0x8823,0x80}, + {0x8824,0x02}, + {0x8825,0xaf}, + {0x8826,0x17}, + {0x8827,0x8f}, + {0x8828,0x17}, + {0x8829,0xd3}, + {0x882a,0xe5}, + {0x882b,0x16}, + {0x882c,0x64}, + {0x882d,0x80}, + {0x882e,0x94}, + {0x882f,0x80}, + {0x8830,0x40}, + {0x8831,0x04}, + {0x8832,0xaf}, + {0x8833,0x15}, + {0x8834,0x80}, + {0x8835,0x02}, + {0x8836,0xaf}, + {0x8837,0x17}, + {0x8838,0x8f}, + {0x8839,0x15}, + {0x883a,0xe5}, + {0x883b,0x16}, + {0x883c,0xfd}, + {0x883d,0x33}, + {0x883e,0x95}, + {0x883f,0xe0}, + {0x8840,0xfc}, + {0x8841,0xed}, + {0x8842,0xae}, + {0x8843,0x04}, + {0x8844,0x78}, + {0x8845,0x02}, + {0x8846,0xc3}, + {0x8847,0x33}, + {0x8848,0xce}, + {0x8849,0x33}, + {0x884a,0xce}, + {0x884b,0xd8}, + {0x884c,0xf9}, + {0x884d,0xff}, + {0x884e,0x24}, + {0x884f,0x01}, + {0x8850,0xfb}, + {0x8851,0xee}, + {0x8852,0x34}, + {0x8853,0x60}, + {0x8854,0x8b}, + {0x8855,0x82}, + {0x8856,0xf5}, + {0x8857,0x83}, + {0x8858,0xe5}, + {0x8859,0x12}, + {0x885a,0xf0}, + {0x885b,0xef}, + {0x885c,0x24}, + {0x885d,0x02}, + {0x885e,0xff}, + {0x885f,0xee}, + {0x8860,0x34}, + {0x8861,0x60}, + {0x8862,0x8f}, + {0x8863,0x82}, + {0x8864,0xf5}, + {0x8865,0x83}, + {0x8866,0xe5}, + {0x8867,0x14}, + {0x8868,0xf0}, + {0x8869,0xed}, + {0x886a,0xae}, + {0x886b,0x04}, + {0x886c,0x78}, + {0x886d,0x02}, + {0x886e,0xc3}, + {0x886f,0x33}, + {0x8870,0xce}, + {0x8871,0x33}, + {0x8872,0xce}, + {0x8873,0xd8}, + {0x8874,0xf9}, + {0x8875,0xff}, + {0x8876,0x24}, + {0x8877,0x03}, + {0x8878,0xfd}, + {0x8879,0xee}, + {0x887a,0x34}, + {0x887b,0x60}, + {0x887c,0x8d}, + {0x887d,0x82}, + {0x887e,0xf5}, + {0x887f,0x83}, + {0x8880,0xe5}, + {0x8881,0x13}, + {0x8882,0xf0}, + {0x8883,0xef}, + {0x8884,0x24}, + {0x8885,0x04}, + {0x8886,0xff}, + {0x8887,0xee}, + {0x8888,0x34}, + {0x8889,0x60}, + {0x888a,0x8f}, + {0x888b,0x82}, + {0x888c,0xf5}, + {0x888d,0x83}, + {0x888e,0xe5}, + {0x888f,0x15}, + {0x8890,0xf0}, + {0x8891,0x15}, + {0x8892,0x16}, + {0x8893,0xc3}, + {0x8894,0xe5}, + {0x8895,0x16}, + {0x8896,0x64}, + {0x8897,0x80}, + {0x8898,0x94}, + {0x8899,0x80}, + {0x889a,0x40}, + {0x889b,0x03}, + {0x889c,0x02}, + {0x889d,0x07}, + {0x889e,0x4c}, + {0x889f,0xc2}, + {0x88a0,0x30}, + {0x88a1,0x22}, + {0x88a2,0xe8}, + {0x88a3,0x8f}, + {0x88a4,0xf0}, + {0x88a5,0xa4}, + {0x88a6,0xcc}, + {0x88a7,0x8b}, + {0x88a8,0xf0}, + {0x88a9,0xa4}, + {0x88aa,0x2c}, + {0x88ab,0xfc}, + {0x88ac,0xe9}, + {0x88ad,0x8e}, + {0x88ae,0xf0}, + {0x88af,0xa4}, + {0x88b0,0x2c}, + {0x88b1,0xfc}, + {0x88b2,0x8a}, + {0x88b3,0xf0}, + {0x88b4,0xed}, + {0x88b5,0xa4}, + {0x88b6,0x2c}, + {0x88b7,0xfc}, + {0x88b8,0xea}, + {0x88b9,0x8e}, + {0x88ba,0xf0}, + {0x88bb,0xa4}, + {0x88bc,0xcd}, + {0x88bd,0xa8}, + {0x88be,0xf0}, + {0x88bf,0x8b}, + {0x88c0,0xf0}, + {0x88c1,0xa4}, + {0x88c2,0x2d}, + {0x88c3,0xcc}, + {0x88c4,0x38}, + {0x88c5,0x25}, + {0x88c6,0xf0}, + {0x88c7,0xfd}, + {0x88c8,0xe9}, + {0x88c9,0x8f}, + {0x88ca,0xf0}, + {0x88cb,0xa4}, + {0x88cc,0x2c}, + {0x88cd,0xcd}, + {0x88ce,0x35}, + {0x88cf,0xf0}, + {0x88d0,0xfc}, + {0x88d1,0xeb}, + {0x88d2,0x8e}, + {0x88d3,0xf0}, + {0x88d4,0xa4}, + {0x88d5,0xfe}, + {0x88d6,0xa9}, + {0x88d7,0xf0}, + {0x88d8,0xeb}, + {0x88d9,0x8f}, + {0x88da,0xf0}, + {0x88db,0xa4}, + {0x88dc,0xcf}, + {0x88dd,0xc5}, + {0x88de,0xf0}, + {0x88df,0x2e}, + {0x88e0,0xcd}, + {0x88e1,0x39}, + {0x88e2,0xfe}, + {0x88e3,0xe4}, + {0x88e4,0x3c}, + {0x88e5,0xfc}, + {0x88e6,0xea}, + {0x88e7,0xa4}, + {0x88e8,0x2d}, + {0x88e9,0xce}, + {0x88ea,0x35}, + {0x88eb,0xf0}, + {0x88ec,0xfd}, + {0x88ed,0xe4}, + {0x88ee,0x3c}, + {0x88ef,0xfc}, + {0x88f0,0x22}, + {0x88f1,0x75}, + {0x88f2,0xf0}, + {0x88f3,0x08}, + {0x88f4,0x75}, + {0x88f5,0x82}, + {0x88f6,0x00}, + {0x88f7,0xef}, + {0x88f8,0x2f}, + {0x88f9,0xff}, + {0x88fa,0xee}, + {0x88fb,0x33}, + {0x88fc,0xfe}, + {0x88fd,0xcd}, + {0x88fe,0x33}, + {0x88ff,0xcd}, + {0x8900,0xcc}, + {0x8901,0x33}, + {0x8902,0xcc}, + {0x8903,0xc5}, + {0x8904,0x82}, + {0x8905,0x33}, + {0x8906,0xc5}, + {0x8907,0x82}, + {0x8908,0x9b}, + {0x8909,0xed}, + {0x890a,0x9a}, + {0x890b,0xec}, + {0x890c,0x99}, + {0x890d,0xe5}, + {0x890e,0x82}, + {0x890f,0x98}, + {0x8910,0x40}, + {0x8911,0x0c}, + {0x8912,0xf5}, + {0x8913,0x82}, + {0x8914,0xee}, + {0x8915,0x9b}, + {0x8916,0xfe}, + {0x8917,0xed}, + {0x8918,0x9a}, + {0x8919,0xfd}, + {0x891a,0xec}, + {0x891b,0x99}, + {0x891c,0xfc}, + {0x891d,0x0f}, + {0x891e,0xd5}, + {0x891f,0xf0}, + {0x8920,0xd6}, + {0x8921,0xe4}, + {0x8922,0xce}, + {0x8923,0xfb}, + {0x8924,0xe4}, + {0x8925,0xcd}, + {0x8926,0xfa}, + {0x8927,0xe4}, + {0x8928,0xcc}, + {0x8929,0xf9}, + {0x892a,0xa8}, + {0x892b,0x82}, + {0x892c,0x22}, + {0x892d,0xb8}, + {0x892e,0x00}, + {0x892f,0xc1}, + {0x8930,0xb9}, + {0x8931,0x00}, + {0x8932,0x59}, + {0x8933,0xba}, + {0x8934,0x00}, + {0x8935,0x2d}, + {0x8936,0xec}, + {0x8937,0x8b}, + {0x8938,0xf0}, + {0x8939,0x84}, + {0x893a,0xcf}, + {0x893b,0xce}, + {0x893c,0xcd}, + {0x893d,0xfc}, + {0x893e,0xe5}, + {0x893f,0xf0}, + {0x8940,0xcb}, + {0x8941,0xf9}, + {0x8942,0x78}, + {0x8943,0x18}, + {0x8944,0xef}, + {0x8945,0x2f}, + {0x8946,0xff}, + {0x8947,0xee}, + {0x8948,0x33}, + {0x8949,0xfe}, + {0x894a,0xed}, + {0x894b,0x33}, + {0x894c,0xfd}, + {0x894d,0xec}, + {0x894e,0x33}, + {0x894f,0xfc}, + {0x8950,0xeb}, + {0x8951,0x33}, + {0x8952,0xfb}, + {0x8953,0x10}, + {0x8954,0xd7}, + {0x8955,0x03}, + {0x8956,0x99}, + {0x8957,0x40}, + {0x8958,0x04}, + {0x8959,0xeb}, + {0x895a,0x99}, + {0x895b,0xfb}, + {0x895c,0x0f}, + {0x895d,0xd8}, + {0x895e,0xe5}, + {0x895f,0xe4}, + {0x8960,0xf9}, + {0x8961,0xfa}, + {0x8962,0x22}, + {0x8963,0x78}, + {0x8964,0x18}, + {0x8965,0xef}, + {0x8966,0x2f}, + {0x8967,0xff}, + {0x8968,0xee}, + {0x8969,0x33}, + {0x896a,0xfe}, + {0x896b,0xed}, + {0x896c,0x33}, + {0x896d,0xfd}, + {0x896e,0xec}, + {0x896f,0x33}, + {0x8970,0xfc}, + {0x8971,0xc9}, + {0x8972,0x33}, + {0x8973,0xc9}, + {0x8974,0x10}, + {0x8975,0xd7}, + {0x8976,0x05}, + {0x8977,0x9b}, + {0x8978,0xe9}, + {0x8979,0x9a}, + {0x897a,0x40}, + {0x897b,0x07}, + {0x897c,0xec}, + {0x897d,0x9b}, + {0x897e,0xfc}, + {0x897f,0xe9}, + {0x8980,0x9a}, + {0x8981,0xf9}, + {0x8982,0x0f}, + {0x8983,0xd8}, + {0x8984,0xe0}, + {0x8985,0xe4}, + {0x8986,0xc9}, + {0x8987,0xfa}, + {0x8988,0xe4}, + {0x8989,0xcc}, + {0x898a,0xfb}, + {0x898b,0x22}, + {0x898c,0x75}, + {0x898d,0xf0}, + {0x898e,0x10}, + {0x898f,0xef}, + {0x8990,0x2f}, + {0x8991,0xff}, + {0x8992,0xee}, + {0x8993,0x33}, + {0x8994,0xfe}, + {0x8995,0xed}, + {0x8996,0x33}, + {0x8997,0xfd}, + {0x8998,0xcc}, + {0x8999,0x33}, + {0x899a,0xcc}, + {0x899b,0xc8}, + {0x899c,0x33}, + {0x899d,0xc8}, + {0x899e,0x10}, + {0x899f,0xd7}, + {0x89a0,0x07}, + {0x89a1,0x9b}, + {0x89a2,0xec}, + {0x89a3,0x9a}, + {0x89a4,0xe8}, + {0x89a5,0x99}, + {0x89a6,0x40}, + {0x89a7,0x0a}, + {0x89a8,0xed}, + {0x89a9,0x9b}, + {0x89aa,0xfd}, + {0x89ab,0xec}, + {0x89ac,0x9a}, + {0x89ad,0xfc}, + {0x89ae,0xe8}, + {0x89af,0x99}, + {0x89b0,0xf8}, + {0x89b1,0x0f}, + {0x89b2,0xd5}, + {0x89b3,0xf0}, + {0x89b4,0xda}, + {0x89b5,0xe4}, + {0x89b6,0xcd}, + {0x89b7,0xfb}, + {0x89b8,0xe4}, + {0x89b9,0xcc}, + {0x89ba,0xfa}, + {0x89bb,0xe4}, + {0x89bc,0xc8}, + {0x89bd,0xf9}, + {0x89be,0x22}, + {0x89bf,0xe8}, + {0x89c0,0x60}, + {0x89c1,0x0f}, + {0x89c2,0xec}, + {0x89c3,0xc3}, + {0x89c4,0x13}, + {0x89c5,0xfc}, + {0x89c6,0xed}, + {0x89c7,0x13}, + {0x89c8,0xfd}, + {0x89c9,0xee}, + {0x89ca,0x13}, + {0x89cb,0xfe}, + {0x89cc,0xef}, + {0x89cd,0x13}, + {0x89ce,0xff}, + {0x89cf,0xd8}, + {0x89d0,0xf1}, + {0x89d1,0x22}, + {0x89d2,0xe8}, + {0x89d3,0x60}, + {0x89d4,0x0f}, + {0x89d5,0xef}, + {0x89d6,0xc3}, + {0x89d7,0x33}, + {0x89d8,0xff}, + {0x89d9,0xee}, + {0x89da,0x33}, + {0x89db,0xfe}, + {0x89dc,0xed}, + {0x89dd,0x33}, + {0x89de,0xfd}, + {0x89df,0xec}, + {0x89e0,0x33}, + {0x89e1,0xfc}, + {0x89e2,0xd8}, + {0x89e3,0xf1}, + {0x89e4,0x22}, + {0x89e5,0xe4}, + {0x89e6,0x93}, + {0x89e7,0xfc}, + {0x89e8,0x74}, + {0x89e9,0x01}, + {0x89ea,0x93}, + {0x89eb,0xfd}, + {0x89ec,0x74}, + {0x89ed,0x02}, + {0x89ee,0x93}, + {0x89ef,0xfe}, + {0x89f0,0x74}, + {0x89f1,0x03}, + {0x89f2,0x93}, + {0x89f3,0xff}, + {0x89f4,0x22}, + {0x89f5,0xd0}, + {0x89f6,0x83}, + {0x89f7,0xd0}, + {0x89f8,0x82}, + {0x89f9,0xf8}, + {0x89fa,0xe4}, + {0x89fb,0x93}, + {0x89fc,0x70}, + {0x89fd,0x12}, + {0x89fe,0x74}, + {0x89ff,0x01}, + {0x8a00,0x93}, + {0x8a01,0x70}, + {0x8a02,0x0d}, + {0x8a03,0xa3}, + {0x8a04,0xa3}, + {0x8a05,0x93}, + {0x8a06,0xf8}, + {0x8a07,0x74}, + {0x8a08,0x01}, + {0x8a09,0x93}, + {0x8a0a,0xf5}, + {0x8a0b,0x82}, + {0x8a0c,0x88}, + {0x8a0d,0x83}, + {0x8a0e,0xe4}, + {0x8a0f,0x73}, + {0x8a10,0x74}, + {0x8a11,0x02}, + {0x8a12,0x93}, + {0x8a13,0x68}, + {0x8a14,0x60}, + {0x8a15,0xef}, + {0x8a16,0xa3}, + {0x8a17,0xa3}, + {0x8a18,0xa3}, + {0x8a19,0x80}, + {0x8a1a,0xdf}, + {0x8a1b,0x75}, + {0x8a1c,0x12}, + {0x8a1d,0x0a}, + {0x8a1e,0xa2}, + {0x8a1f,0xaf}, + {0x8a20,0x92}, + {0x8a21,0x32}, + {0x8a22,0xc2}, + {0x8a23,0xaf}, + {0x8a24,0xc2}, + {0x8a25,0x33}, + {0x8a26,0x12}, + {0x8a27,0x01}, + {0x8a28,0x6a}, + {0x8a29,0x12}, + {0x8a2a,0x02}, + {0x8a2b,0x08}, + {0x8a2c,0x12}, + {0x8a2d,0x01}, + {0x8a2e,0x6a}, + {0x8a2f,0x75}, + {0x8a30,0x51}, + {0x8a31,0x05}, + {0x8a32,0xaf}, + {0x8a33,0x51}, + {0x8a34,0x15}, + {0x8a35,0x51}, + {0x8a36,0xef}, + {0x8a37,0x70}, + {0x8a38,0xf9}, + {0x8a39,0xd2}, + {0x8a3a,0x28}, + {0x8a3b,0x12}, + {0x8a3c,0x01}, + {0x8a3d,0x6c}, + {0x8a3e,0x75}, + {0x8a3f,0x51}, + {0x8a40,0x0a}, + {0x8a41,0xaf}, + {0x8a42,0x51}, + {0x8a43,0x15}, + {0x8a44,0x51}, + {0x8a45,0xef}, + {0x8a46,0x70}, + {0x8a47,0xf9}, + {0x8a48,0xc2}, + {0x8a49,0x29}, + {0x8a4a,0x12}, + {0x8a4b,0x01}, + {0x8a4c,0x6c}, + {0x8a4d,0x75}, + {0x8a4e,0x51}, + {0x8a4f,0x05}, + {0x8a50,0xaf}, + {0x8a51,0x51}, + {0x8a52,0x15}, + {0x8a53,0x51}, + {0x8a54,0xef}, + {0x8a55,0x70}, + {0x8a56,0xf9}, + {0x8a57,0xc2}, + {0x8a58,0x28}, + {0x8a59,0x12}, + {0x8a5a,0x01}, + {0x8a5b,0x6c}, + {0x8a5c,0x75}, + {0x8a5d,0x51}, + {0x8a5e,0x05}, + {0x8a5f,0xaf}, + {0x8a60,0x51}, + {0x8a61,0x15}, + {0x8a62,0x51}, + {0x8a63,0xef}, + {0x8a64,0x70}, + {0x8a65,0xf9}, + {0x8a66,0x75}, + {0x8a67,0x13}, + {0x8a68,0x18}, + {0x8a69,0x12}, + {0x8a6a,0x0b}, + {0x8a6b,0x5b}, + {0x8a6c,0x75}, + {0x8a6d,0x51}, + {0x8a6e,0x0a}, + {0x8a6f,0xaf}, + {0x8a70,0x51}, + {0x8a71,0x15}, + {0x8a72,0x51}, + {0x8a73,0xef}, + {0x8a74,0x70}, + {0x8a75,0xf9}, + {0x8a76,0xd2}, + {0x8a77,0x28}, + {0x8a78,0x12}, + {0x8a79,0x01}, + {0x8a7a,0x6c}, + {0x8a7b,0x12}, + {0x8a7c,0x02}, + {0x8a7d,0x25}, + {0x8a7e,0xaf}, + {0x8a7f,0x51}, + {0x8a80,0x15}, + {0x8a81,0x51}, + {0x8a82,0xef}, + {0x8a83,0x70}, + {0x8a84,0xf9}, + {0x8a85,0xc2}, + {0x8a86,0x28}, + {0x8a87,0x12}, + {0x8a88,0x01}, + {0x8a89,0x6c}, + {0x8a8a,0x75}, + {0x8a8b,0x51}, + {0x8a8c,0x0a}, + {0x8a8d,0xaf}, + {0x8a8e,0x51}, + {0x8a8f,0x15}, + {0x8a90,0x51}, + {0x8a91,0xef}, + {0x8a92,0x70}, + {0x8a93,0xf9}, + {0x8a94,0x30}, + {0x8a95,0x11}, + {0x8a96,0x03}, + {0x8a97,0x02}, + {0x8a98,0x0b}, + {0x8a99,0x12}, + {0x8a9a,0x12}, + {0x8a9b,0x01}, + {0x8a9c,0x6a}, + {0x8a9d,0x12}, + {0x8a9e,0x02}, + {0x8a9f,0x08}, + {0x8aa0,0xe5}, + {0x8aa1,0x10}, + {0x8aa2,0xf5}, + {0x8aa3,0x13}, + {0x8aa4,0x12}, + {0x8aa5,0x0b}, + {0x8aa6,0x5b}, + {0x8aa7,0x75}, + {0x8aa8,0x51}, + {0x8aa9,0x0a}, + {0x8aaa,0xaf}, + {0x8aab,0x51}, + {0x8aac,0x15}, + {0x8aad,0x51}, + {0x8aae,0xef}, + {0x8aaf,0x70}, + {0x8ab0,0xf9}, + {0x8ab1,0xd2}, + {0x8ab2,0x28}, + {0x8ab3,0x12}, + {0x8ab4,0x01}, + {0x8ab5,0x6c}, + {0x8ab6,0x12}, + {0x8ab7,0x02}, + {0x8ab8,0x25}, + {0x8ab9,0xaf}, + {0x8aba,0x51}, + {0x8abb,0x15}, + {0x8abc,0x51}, + {0x8abd,0xef}, + {0x8abe,0x70}, + {0x8abf,0xf9}, + {0x8ac0,0xc2}, + {0x8ac1,0x28}, + {0x8ac2,0x12}, + {0x8ac3,0x01}, + {0x8ac4,0x6c}, + {0x8ac5,0x75}, + {0x8ac6,0x51}, + {0x8ac7,0x0a}, + {0x8ac8,0xaf}, + {0x8ac9,0x51}, + {0x8aca,0x15}, + {0x8acb,0x51}, + {0x8acc,0xef}, + {0x8acd,0x70}, + {0x8ace,0xf9}, + {0x8acf,0x30}, + {0x8ad0,0x11}, + {0x8ad1,0x04}, + {0x8ad2,0x15}, + {0x8ad3,0x12}, + {0x8ad4,0x80}, + {0x8ad5,0x45}, + {0x8ad6,0x12}, + {0x8ad7,0x01}, + {0x8ad8,0x6a}, + {0x8ad9,0x12}, + {0x8ada,0x02}, + {0x8adb,0x08}, + {0x8adc,0x85}, + {0x8add,0x11}, + {0x8ade,0x13}, + {0x8adf,0x12}, + {0x8ae0,0x15}, + {0x8ae1,0xa4}, + {0x8ae2,0xc2}, + {0x8ae3,0x09}, + {0x8ae4,0x12}, + {0x8ae5,0x02}, + {0x8ae6,0x0a}, + {0x8ae7,0x75}, + {0x8ae8,0x51}, + {0x8ae9,0x0a}, + {0x8aea,0xaf}, + {0x8aeb,0x51}, + {0x8aec,0x15}, + {0x8aed,0x51}, + {0x8aee,0xef}, + {0x8aef,0x70}, + {0x8af0,0xf9}, + {0x8af1,0xd2}, + {0x8af2,0x28}, + {0x8af3,0x12}, + {0x8af4,0x01}, + {0x8af5,0x6c}, + {0x8af6,0x12}, + {0x8af7,0x02}, + {0x8af8,0x25}, + {0x8af9,0xaf}, + {0x8afa,0x51}, + {0x8afb,0x15}, + {0x8afc,0x51}, + {0x8afd,0xef}, + {0x8afe,0x70}, + {0x8aff,0xf9}, + {0x8b00,0xc2}, + {0x8b01,0x28}, + {0x8b02,0x12}, + {0x8b03,0x01}, + {0x8b04,0x6c}, + {0x8b05,0x75}, + {0x8b06,0x51}, + {0x8b07,0x0a}, + {0x8b08,0xaf}, + {0x8b09,0x51}, + {0x8b0a,0x15}, + {0x8b0b,0x51}, + {0x8b0c,0xef}, + {0x8b0d,0x70}, + {0x8b0e,0xf9}, + {0x8b0f,0x30}, + {0x8b10,0x11}, + {0x8b11,0x06}, + {0x8b12,0x15}, + {0x8b13,0x12}, + {0x8b14,0xd2}, + {0x8b15,0x33}, + {0x8b16,0x80}, + {0x8b17,0x03}, + {0x8b18,0xe4}, + {0x8b19,0xf5}, + {0x8b1a,0x12}, + {0x8b1b,0x12}, + {0x8b1c,0x01}, + {0x8b1d,0x6a}, + {0x8b1e,0x12}, + {0x8b1f,0x02}, + {0x8b20,0x08}, + {0x8b21,0xc2}, + {0x8b22,0x29}, + {0x8b23,0x12}, + {0x8b24,0x01}, + {0x8b25,0x6c}, + {0x8b26,0x75}, + {0x8b27,0x51}, + {0x8b28,0x05}, + {0x8b29,0xaf}, + {0x8b2a,0x51}, + {0x8b2b,0x15}, + {0x8b2c,0x51}, + {0x8b2d,0xef}, + {0x8b2e,0x70}, + {0x8b2f,0xf9}, + {0x8b30,0xd2}, + {0x8b31,0x28}, + {0x8b32,0x12}, + {0x8b33,0x01}, + {0x8b34,0x6c}, + {0x8b35,0x75}, + {0x8b36,0x51}, + {0x8b37,0x05}, + {0x8b38,0xaf}, + {0x8b39,0x51}, + {0x8b3a,0x15}, + {0x8b3b,0x51}, + {0x8b3c,0xef}, + {0x8b3d,0x70}, + {0x8b3e,0xf9}, + {0x8b3f,0x12}, + {0x8b40,0x01}, + {0x8b41,0x6a}, + {0x8b42,0x75}, + {0x8b43,0x51}, + {0x8b44,0x05}, + {0x8b45,0xaf}, + {0x8b46,0x51}, + {0x8b47,0x15}, + {0x8b48,0x51}, + {0x8b49,0xef}, + {0x8b4a,0x70}, + {0x8b4b,0xf9}, + {0x8b4c,0xa2}, + {0x8b4d,0x32}, + {0x8b4e,0x92}, + {0x8b4f,0xaf}, + {0x8b50,0xe5}, + {0x8b51,0x12}, + {0x8b52,0xd3}, + {0x8b53,0x94}, + {0x8b54,0x00}, + {0x8b55,0x40}, + {0x8b56,0x03}, + {0x8b57,0x02}, + {0x8b58,0x0a}, + {0x8b59,0x22}, + {0x8b5a,0x22}, + {0x8b5b,0x12}, + {0x8b5c,0x15}, + {0x8b5d,0xa4}, + {0x8b5e,0xc2}, + {0x8b5f,0x09}, + {0x8b60,0x90}, + {0x8b61,0x30}, + {0x8b62,0x18}, + {0x8b63,0xe5}, + {0x8b64,0x21}, + {0x8b65,0xf0}, + {0x8b66,0x22}, + {0x8b67,0xe5}, + {0x8b68,0x33}, + {0x8b69,0x70}, + {0x8b6a,0x03}, + {0x8b6b,0x02}, + {0x8b6c,0x0c}, + {0x8b6d,0x8f}, + {0x8b6e,0xc2}, + {0x8b6f,0xaf}, + {0x8b70,0xaf}, + {0x8b71,0x33}, + {0x8b72,0xe4}, + {0x8b73,0xf5}, + {0x8b74,0x33}, + {0x8b75,0xd2}, + {0x8b76,0xaf}, + {0x8b77,0x90}, + {0x8b78,0x30}, + {0x8b79,0x25}, + {0x8b7a,0xe0}, + {0x8b7b,0xf5}, + {0x8b7c,0x7d}, + {0x8b7d,0x90}, + {0x8b7e,0x50}, + {0x8b7f,0x82}, + {0x8b80,0xe0}, + {0x8b81,0xf5}, + {0x8b82,0x65}, + {0x8b83,0xa3}, + {0x8b84,0xe0}, + {0x8b85,0xf5}, + {0x8b86,0x66}, + {0x8b87,0xa3}, + {0x8b88,0xe0}, + {0x8b89,0xf5}, + {0x8b8a,0x67}, + {0x8b8b,0xa3}, + {0x8b8c,0xe0}, + {0x8b8d,0xf5}, + {0x8b8e,0x68}, + {0x8b8f,0xef}, + {0x8b90,0x12}, + {0x8b91,0x09}, + {0x8b92,0xf5}, + {0x8b93,0x0b}, + {0x8b94,0xbb}, + {0x8b95,0x03}, + {0x8b96,0x0b}, + {0x8b97,0xd3}, + {0x8b98,0x04}, + {0x8b99,0x0b}, + {0x8b9a,0xee}, + {0x8b9b,0x05}, + {0x8b9c,0x0c}, + {0x8b9d,0x12}, + {0x8b9e,0x06}, + {0x8b9f,0x0c}, + {0x8ba0,0x00}, + {0x8ba1,0x08}, + {0x8ba2,0x0c}, + {0x8ba3,0x1f}, + {0x8ba4,0x10}, + {0x8ba5,0x0c}, + {0x8ba6,0x33}, + {0x8ba7,0x12}, + {0x8ba8,0x0c}, + {0x8ba9,0x38}, + {0x8baa,0x20}, + {0x8bab,0x0c}, + {0x8bac,0x46}, + {0x8bad,0x21}, + {0x8bae,0x0c}, + {0x8baf,0x4b}, + {0x8bb0,0x30}, + {0x8bb1,0x0c}, + {0x8bb2,0x74}, + {0x8bb3,0x50}, + {0x8bb4,0x0c}, + {0x8bb5,0x56}, + {0x8bb6,0xd8}, + {0x8bb7,0x00}, + {0x8bb8,0x00}, + {0x8bb9,0x0c}, + {0x8bba,0x81}, + {0x8bbb,0x30}, + {0x8bbc,0x00}, + {0x8bbd,0x03}, + {0x8bbe,0x02}, + {0x8bbf,0x0c}, + {0x8bc0,0x81}, + {0x8bc1,0x20}, + {0x8bc2,0x07}, + {0x8bc3,0x06}, + {0x8bc4,0x20}, + {0x8bc5,0x06}, + {0x8bc6,0x03}, + {0x8bc7,0xc3}, + {0x8bc8,0x80}, + {0x8bc9,0x01}, + {0x8bca,0xd3}, + {0x8bcb,0x92}, + {0x8bcc,0x36}, + {0x8bcd,0xd2}, + {0x8bce,0x07}, + {0x8bcf,0xc2}, + {0x8bd0,0x06}, + {0x8bd1,0x80}, + {0x8bd2,0x16}, + {0x8bd3,0x30}, + {0x8bd4,0x00}, + {0x8bd5,0x03}, + {0x8bd6,0x02}, + {0x8bd7,0x0c}, + {0x8bd8,0x81}, + {0x8bd9,0x20}, + {0x8bda,0x07}, + {0x8bdb,0x06}, + {0x8bdc,0x20}, + {0x8bdd,0x06}, + {0x8bde,0x03}, + {0x8bdf,0xc3}, + {0x8be0,0x80}, + {0x8be1,0x01}, + {0x8be2,0xd3}, + {0x8be3,0x92}, + {0x8be4,0x36}, + {0x8be5,0xd2}, + {0x8be6,0x07}, + {0x8be7,0xd2}, + {0x8be8,0x06}, + {0x8be9,0x12}, + {0x8bea,0x02}, + {0x8beb,0x90}, + {0x8bec,0x80}, + {0x8bed,0x1e}, + {0x8bee,0x30}, + {0x8bef,0x00}, + {0x8bf0,0x03}, + {0x8bf1,0x02}, + {0x8bf2,0x0c}, + {0x8bf3,0x81}, + {0x8bf4,0xc2}, + {0x8bf5,0x07}, + {0x8bf6,0xd2}, + {0x8bf7,0x06}, + {0x8bf8,0x12}, + {0x8bf9,0x02}, + {0x8bfa,0xa5}, + {0x8bfb,0xc2}, + {0x8bfc,0x04}, + {0x8bfd,0x02}, + {0x8bfe,0x0c}, + {0x8bff,0x81}, + {0x8c00,0x12}, + {0x8c01,0x02}, + {0x8c02,0x40}, + {0x8c03,0x30}, + {0x8c04,0x05}, + {0x8c05,0x06}, + {0x8c06,0xe4}, + {0x8c07,0xf5}, + {0x8c08,0x0c}, + {0x8c09,0x12}, + {0x8c0a,0x0f}, + {0x8c0b,0x52}, + {0x8c0c,0xc2}, + {0x8c0d,0x31}, + {0x8c0e,0xd2}, + {0x8c0f,0x34}, + {0x8c10,0x80}, + {0x8c11,0x6f}, + {0x8c12,0x30}, + {0x8c13,0x07}, + {0x8c14,0x6c}, + {0x8c15,0x30}, + {0x8c16,0x06}, + {0x8c17,0x69}, + {0x8c18,0x12}, + {0x8c19,0x02}, + {0x8c1a,0x90}, + {0x8c1b,0xd2}, + {0x8c1c,0x31}, + {0x8c1d,0x80}, + {0x8c1e,0x62}, + {0x8c1f,0x20}, + {0x8c20,0x07}, + {0x8c21,0x03}, + {0x8c22,0x30}, + {0x8c23,0x06}, + {0x8c24,0x09}, + {0x8c25,0xe5}, + {0x8c26,0x7d}, + {0x8c27,0x64}, + {0x8c28,0x0e}, + {0x8c29,0x70}, + {0x8c2a,0x56}, + {0x8c2b,0x20}, + {0x8c2c,0x00}, + {0x8c2d,0x53}, + {0x8c2e,0x12}, + {0x8c2f,0x05}, + {0x8c30,0x39}, + {0x8c31,0x80}, + {0x8c32,0x4e}, + {0x8c33,0x12}, + {0x8c34,0x07}, + {0x8c35,0x02}, + {0x8c36,0x80}, + {0x8c37,0x49}, + {0x8c38,0x30}, + {0x8c39,0x05}, + {0x8c3a,0x46}, + {0x8c3b,0x20}, + {0x8c3c,0x07}, + {0x8c3d,0x43}, + {0x8c3e,0x20}, + {0x8c3f,0x06}, + {0x8c40,0x40}, + {0x8c41,0x12}, + {0x8c42,0x16}, + {0x8c43,0xc4}, + {0x8c44,0x80}, + {0x8c45,0x3b}, + {0x8c46,0x12}, + {0x8c47,0x13}, + {0x8c48,0x10}, + {0x8c49,0x80}, + {0x8c4a,0x36}, + {0x8c4b,0x20}, + {0x8c4c,0x07}, + {0x8c4d,0x33}, + {0x8c4e,0x20}, + {0x8c4f,0x06}, + {0x8c50,0x30}, + {0x8c51,0x12}, + {0x8c52,0x16}, + {0x8c53,0xd3}, + {0x8c54,0x80}, + {0x8c55,0x2b}, + {0x8c56,0xe5}, + {0x8c57,0x7d}, + {0x8c58,0x64}, + {0x8c59,0x01}, + {0x8c5a,0x70}, + {0x8c5b,0x25}, + {0x8c5c,0xd2}, + {0x8c5d,0x35}, + {0x8c5e,0x90}, + {0x8c5f,0x50}, + {0x8c60,0x82}, + {0x8c61,0xe5}, + {0x8c62,0x73}, + {0x8c63,0xf0}, + {0x8c64,0xa3}, + {0x8c65,0xe5}, + {0x8c66,0x74}, + {0x8c67,0xf0}, + {0x8c68,0xa3}, + {0x8c69,0xe5}, + {0x8c6a,0x75}, + {0x8c6b,0xf0}, + {0x8c6c,0xa3}, + {0x8c6d,0xe5}, + {0x8c6e,0x76}, + {0x8c6f,0xf0}, + {0x8c70,0xc2}, + {0x8c71,0x35}, + {0x8c72,0x80}, + {0x8c73,0x0d}, + {0x8c74,0x90}, + {0x8c75,0x50}, + {0x8c76,0x82}, + {0x8c77,0x30}, + {0x8c78,0x33}, + {0x8c79,0x05}, + {0x8c7a,0x74}, + {0x8c7b,0x55}, + {0x8c7c,0xf0}, + {0x8c7d,0x80}, + {0x8c7e,0x02}, + {0x8c7f,0xe4}, + {0x8c80,0xf0}, + {0x8c81,0x20}, + {0x8c82,0x07}, + {0x8c83,0x06}, + {0x8c84,0x30}, + {0x8c85,0x06}, + {0x8c86,0x03}, + {0x8c87,0x30}, + {0x8c88,0x04}, + {0x8c89,0x05}, + {0x8c8a,0x90}, + {0x8c8b,0x30}, + {0x8c8c,0x25}, + {0x8c8d,0xe4}, + {0x8c8e,0xf0}, + {0x8c8f,0x22}, + {0x8c90,0xc0}, + {0x8c91,0xe0}, + {0x8c92,0xc0}, + {0x8c93,0xf0}, + {0x8c94,0xc0}, + {0x8c95,0x83}, + {0x8c96,0xc0}, + {0x8c97,0x82}, + {0x8c98,0xc0}, + {0x8c99,0xd0}, + {0x8c9a,0x75}, + {0x8c9b,0xd0}, + {0x8c9c,0x00}, + {0x8c9d,0xc0}, + {0x8c9e,0x00}, + {0x8c9f,0xc0}, + {0x8ca0,0x01}, + {0x8ca1,0xc0}, + {0x8ca2,0x02}, + {0x8ca3,0xc0}, + {0x8ca4,0x03}, + {0x8ca5,0xc0}, + {0x8ca6,0x04}, + {0x8ca7,0xc0}, + {0x8ca8,0x05}, + {0x8ca9,0xc0}, + {0x8caa,0x06}, + {0x8cab,0xc0}, + {0x8cac,0x07}, + {0x8cad,0x90}, + {0x8cae,0x3f}, + {0x8caf,0x0c}, + {0x8cb0,0xe0}, + {0x8cb1,0xf5}, + {0x8cb2,0x08}, + {0x8cb3,0xe5}, + {0x8cb4,0x08}, + {0x8cb5,0x20}, + {0x8cb6,0xe3}, + {0x8cb7,0x03}, + {0x8cb8,0x02}, + {0x8cb9,0x0d}, + {0x8cba,0x41}, + {0x8cbb,0x30}, + {0x8cbc,0x35}, + {0x8cbd,0x03}, + {0x8cbe,0x02}, + {0x8cbf,0x0d}, + {0x8cc0,0x41}, + {0x8cc1,0x90}, + {0x8cc2,0x60}, + {0x8cc3,0x16}, + {0x8cc4,0xe0}, + {0x8cc5,0xf5}, + {0x8cc6,0x69}, + {0x8cc7,0xa3}, + {0x8cc8,0xe0}, + {0x8cc9,0xf5}, + {0x8cca,0x6a}, + {0x8ccb,0x90}, + {0x8ccc,0x60}, + {0x8ccd,0x1e}, + {0x8cce,0xe0}, + {0x8ccf,0xf5}, + {0x8cd0,0x6b}, + {0x8cd1,0xa3}, + {0x8cd2,0xe0}, + {0x8cd3,0xf5}, + {0x8cd4,0x6c}, + {0x8cd5,0x90}, + {0x8cd6,0x60}, + {0x8cd7,0x26}, + {0x8cd8,0xe0}, + {0x8cd9,0xf5}, + {0x8cda,0x6d}, + {0x8cdb,0xa3}, + {0x8cdc,0xe0}, + {0x8cdd,0xf5}, + {0x8cde,0x6e}, + {0x8cdf,0x90}, + {0x8ce0,0x60}, + {0x8ce1,0x2e}, + {0x8ce2,0xe0}, + {0x8ce3,0xf5}, + {0x8ce4,0x6f}, + {0x8ce5,0xa3}, + {0x8ce6,0xe0}, + {0x8ce7,0xf5}, + {0x8ce8,0x70}, + {0x8ce9,0x90}, + {0x8cea,0x60}, + {0x8ceb,0x36}, + {0x8cec,0x12}, + {0x8ced,0x00}, + {0x8cee,0x16}, + {0x8cef,0x12}, + {0x8cf0,0x01}, + {0x8cf1,0xbf}, + {0x8cf2,0x40}, + {0x8cf3,0x06}, + {0x8cf4,0x75}, + {0x8cf5,0x2a}, + {0x8cf6,0xff}, + {0x8cf7,0x75}, + {0x8cf8,0x2b}, + {0x8cf9,0xff}, + {0x8cfa,0x85}, + {0x8cfb,0x2a}, + {0x8cfc,0x73}, + {0x8cfd,0x85}, + {0x8cfe,0x2b}, + {0x8cff,0x74}, + {0x8d00,0x90}, + {0x8d01,0x60}, + {0x8d02,0x1a}, + {0x8d03,0xe0}, + {0x8d04,0xf5}, + {0x8d05,0x69}, + {0x8d06,0xa3}, + {0x8d07,0xe0}, + {0x8d08,0xf5}, + {0x8d09,0x6a}, + {0x8d0a,0x90}, + {0x8d0b,0x60}, + {0x8d0c,0x22}, + {0x8d0d,0xe0}, + {0x8d0e,0xf5}, + {0x8d0f,0x6b}, + {0x8d10,0xa3}, + {0x8d11,0xe0}, + {0x8d12,0xf5}, + {0x8d13,0x6c}, + {0x8d14,0x90}, + {0x8d15,0x60}, + {0x8d16,0x2a}, + {0x8d17,0xe0}, + {0x8d18,0xf5}, + {0x8d19,0x6d}, + {0x8d1a,0xa3}, + {0x8d1b,0xe0}, + {0x8d1c,0xf5}, + {0x8d1d,0x6e}, + {0x8d1e,0x90}, + {0x8d1f,0x60}, + {0x8d20,0x32}, + {0x8d21,0xe0}, + {0x8d22,0xf5}, + {0x8d23,0x6f}, + {0x8d24,0xa3}, + {0x8d25,0xe0}, + {0x8d26,0xf5}, + {0x8d27,0x70}, + {0x8d28,0x90}, + {0x8d29,0x60}, + {0x8d2a,0x3a}, + {0x8d2b,0x12}, + {0x8d2c,0x00}, + {0x8d2d,0x16}, + {0x8d2e,0x12}, + {0x8d2f,0x01}, + {0x8d30,0xbf}, + {0x8d31,0x40}, + {0x8d32,0x06}, + {0x8d33,0x75}, + {0x8d34,0x2a}, + {0x8d35,0xff}, + {0x8d36,0x75}, + {0x8d37,0x2b}, + {0x8d38,0xff}, + {0x8d39,0x85}, + {0x8d3a,0x2a}, + {0x8d3b,0x75}, + {0x8d3c,0x85}, + {0x8d3d,0x2b}, + {0x8d3e,0x76}, + {0x8d3f,0xd2}, + {0x8d40,0x3d}, + {0x8d41,0xe5}, + {0x8d42,0x08}, + {0x8d43,0x30}, + {0x8d44,0xe5}, + {0x8d45,0x44}, + {0x8d46,0x90}, + {0x8d47,0x56}, + {0x8d48,0x90}, + {0x8d49,0xe0}, + {0x8d4a,0xf5}, + {0x8d4b,0x55}, + {0x8d4c,0xe5}, + {0x8d4d,0x7a}, + {0x8d4e,0x24}, + {0x8d4f,0x02}, + {0x8d50,0xff}, + {0x8d51,0xe4}, + {0x8d52,0x33}, + {0x8d53,0xfe}, + {0x8d54,0xad}, + {0x8d55,0x55}, + {0x8d56,0xc3}, + {0x8d57,0xef}, + {0x8d58,0x9d}, + {0x8d59,0x74}, + {0x8d5a,0x80}, + {0x8d5b,0xf8}, + {0x8d5c,0x6e}, + {0x8d5d,0x98}, + {0x8d5e,0x50}, + {0x8d5f,0x02}, + {0x8d60,0x80}, + {0x8d61,0x01}, + {0x8d62,0xc3}, + {0x8d63,0x92}, + {0x8d64,0x27}, + {0x8d65,0xaf}, + {0x8d66,0x55}, + {0x8d67,0xef}, + {0x8d68,0x24}, + {0x8d69,0x02}, + {0x8d6a,0xff}, + {0x8d6b,0xe4}, + {0x8d6c,0x33}, + {0x8d6d,0xfe}, + {0x8d6e,0xc3}, + {0x8d6f,0xef}, + {0x8d70,0x95}, + {0x8d71,0x7a}, + {0x8d72,0x74}, + {0x8d73,0x80}, + {0x8d74,0xf8}, + {0x8d75,0x6e}, + {0x8d76,0x98}, + {0x8d77,0x50}, + {0x8d78,0x02}, + {0x8d79,0x80}, + {0x8d7a,0x02}, + {0x8d7b,0xa2}, + {0x8d7c,0x27}, + {0x8d7d,0x92}, + {0x8d7e,0x27}, + {0x8d7f,0x30}, + {0x8d80,0x27}, + {0x8d81,0x04}, + {0x8d82,0xaf}, + {0x8d83,0x55}, + {0x8d84,0x80}, + {0x8d85,0x02}, + {0x8d86,0xaf}, + {0x8d87,0x7a}, + {0x8d88,0x8f}, + {0x8d89,0x7a}, + {0x8d8a,0xe5}, + {0x8d8b,0x08}, + {0x8d8c,0x30}, + {0x8d8d,0xe1}, + {0x8d8e,0x08}, + {0x8d8f,0x90}, + {0x8d90,0x30}, + {0x8d91,0x24}, + {0x8d92,0xe0}, + {0x8d93,0xf5}, + {0x8d94,0x33}, + {0x8d95,0xe4}, + {0x8d96,0xf0}, + {0x8d97,0x90}, + {0x8d98,0x3f}, + {0x8d99,0x0c}, + {0x8d9a,0xe5}, + {0x8d9b,0x08}, + {0x8d9c,0xf0}, + {0x8d9d,0xd0}, + {0x8d9e,0x07}, + {0x8d9f,0xd0}, + {0x8da0,0x06}, + {0x8da1,0xd0}, + {0x8da2,0x05}, + {0x8da3,0xd0}, + {0x8da4,0x04}, + {0x8da5,0xd0}, + {0x8da6,0x03}, + {0x8da7,0xd0}, + {0x8da8,0x02}, + {0x8da9,0xd0}, + {0x8daa,0x01}, + {0x8dab,0xd0}, + {0x8dac,0x00}, + {0x8dad,0xd0}, + {0x8dae,0xd0}, + {0x8daf,0xd0}, + {0x8db0,0x82}, + {0x8db1,0xd0}, + {0x8db2,0x83}, + {0x8db3,0xd0}, + {0x8db4,0xf0}, + {0x8db5,0xd0}, + {0x8db6,0xe0}, + {0x8db7,0x32}, + {0x8db8,0x30}, + {0x8db9,0x04}, + {0x8dba,0x03}, + {0x8dbb,0x02}, + {0x8dbc,0x0e}, + {0x8dbd,0xa3}, + {0x8dbe,0xd2}, + {0x8dbf,0x04}, + {0x8dc0,0xe5}, + {0x8dc1,0x7d}, + {0x8dc2,0xb4}, + {0x8dc3,0x01}, + {0x8dc4,0x06}, + {0x8dc5,0x12}, + {0x8dc6,0x16}, + {0x8dc7,0xa4}, + {0x8dc8,0x02}, + {0x8dc9,0x0e}, + {0x8dca,0x9c}, + {0x8dcb,0xe5}, + {0x8dcc,0x7d}, + {0x8dcd,0xb4}, + {0x8dce,0x02}, + {0x8dcf,0x06}, + {0x8dd0,0x12}, + {0x8dd1,0x16}, + {0x8dd2,0xb5}, + {0x8dd3,0x02}, + {0x8dd4,0x0e}, + {0x8dd5,0x9c}, + {0x8dd6,0xe5}, + {0x8dd7,0x7d}, + {0x8dd8,0xb4}, + {0x8dd9,0x03}, + {0x8dda,0x05}, + {0x8ddb,0xe4}, + {0x8ddc,0xf5}, + {0x8ddd,0x0c}, + {0x8dde,0x80}, + {0x8ddf,0x08}, + {0x8de0,0xe5}, + {0x8de1,0x7d}, + {0x8de2,0xb4}, + {0x8de3,0x04}, + {0x8de4,0x09}, + {0x8de5,0x85}, + {0x8de6,0x7b}, + {0x8de7,0x0c}, + {0x8de8,0x12}, + {0x8de9,0x0f}, + {0x8dea,0x52}, + {0x8deb,0x02}, + {0x8dec,0x0e}, + {0x8ded,0x9c}, + {0x8dee,0xe5}, + {0x8def,0x7d}, + {0x8df0,0x64}, + {0x8df1,0x0f}, + {0x8df2,0x70}, + {0x8df3,0x1f}, + {0x8df4,0x12}, + {0x8df5,0x02}, + {0x8df6,0xbd}, + {0x8df7,0x40}, + {0x8df8,0x06}, + {0x8df9,0x7e}, + {0x8dfa,0x00}, + {0x8dfb,0x7f}, + {0x8dfc,0xff}, + {0x8dfd,0x80}, + {0x8dfe,0x04}, + {0x8dff,0xae}, + {0x8e00,0x67}, + {0x8e01,0xaf}, + {0x8e02,0x68}, + {0x8e03,0x12}, + {0x8e04,0x02}, + {0x8e05,0x58}, + {0x8e06,0xc3}, + {0x8e07,0x33}, + {0x8e08,0xce}, + {0x8e09,0x33}, + {0x8e0a,0xce}, + {0x8e0b,0xd8}, + {0x8e0c,0xf9}, + {0x8e0d,0x12}, + {0x8e0e,0x0e}, + {0x8e0f,0xa4}, + {0x8e10,0x02}, + {0x8e11,0x0e}, + {0x8e12,0x9c}, + {0x8e13,0xe5}, + {0x8e14,0x7d}, + {0x8e15,0x64}, + {0x8e16,0x10}, + {0x8e17,0x60}, + {0x8e18,0x03}, + {0x8e19,0x02}, + {0x8e1a,0x0e}, + {0x8e1b,0x9c}, + {0x8e1c,0xf5}, + {0x8e1d,0x65}, + {0x8e1e,0xf5}, + {0x8e1f,0x66}, + {0x8e20,0xf5}, + {0x8e21,0x67}, + {0x8e22,0xab}, + {0x8e23,0x68}, + {0x8e24,0xaa}, + {0x8e25,0x67}, + {0x8e26,0xa9}, + {0x8e27,0x66}, + {0x8e28,0xa8}, + {0x8e29,0x65}, + {0x8e2a,0x12}, + {0x8e2b,0x01}, + {0x8e2c,0xa0}, + {0x8e2d,0xfe}, + {0x8e2e,0xe4}, + {0x8e2f,0xfc}, + {0x8e30,0xfd}, + {0x8e31,0x12}, + {0x8e32,0x01}, + {0x8e33,0xe7}, + {0x8e34,0xe4}, + {0x8e35,0x7b}, + {0x8e36,0xff}, + {0x8e37,0xfa}, + {0x8e38,0xf9}, + {0x8e39,0xf8}, + {0x8e3a,0x12}, + {0x8e3b,0x02}, + {0x8e3c,0x6d}, + {0x8e3d,0x85}, + {0x8e3e,0x49}, + {0x8e3f,0x82}, + {0x8e40,0x85}, + {0x8e41,0x48}, + {0x8e42,0x83}, + {0x8e43,0xe4}, + {0x8e44,0x93}, + {0x8e45,0xff}, + {0x8e46,0xe4}, + {0x8e47,0xfc}, + {0x8e48,0xfd}, + {0x8e49,0xfe}, + {0x8e4a,0xe5}, + {0x8e4b,0x68}, + {0x8e4c,0x2f}, + {0x8e4d,0xf5}, + {0x8e4e,0x68}, + {0x8e4f,0xee}, + {0x8e50,0x35}, + {0x8e51,0x67}, + {0x8e52,0xf5}, + {0x8e53,0x67}, + {0x8e54,0xed}, + {0x8e55,0x35}, + {0x8e56,0x66}, + {0x8e57,0xf5}, + {0x8e58,0x66}, + {0x8e59,0xec}, + {0x8e5a,0x35}, + {0x8e5b,0x65}, + {0x8e5c,0xf5}, + {0x8e5d,0x65}, + {0x8e5e,0x12}, + {0x8e5f,0x02}, + {0x8e60,0xbd}, + {0x8e61,0x40}, + {0x8e62,0x04}, + {0x8e63,0x7f}, + {0x8e64,0xff}, + {0x8e65,0x80}, + {0x8e66,0x04}, + {0x8e67,0xae}, + {0x8e68,0x67}, + {0x8e69,0xaf}, + {0x8e6a,0x68}, + {0x8e6b,0x12}, + {0x8e6c,0x02}, + {0x8e6d,0x58}, + {0x8e6e,0xc3}, + {0x8e6f,0x33}, + {0x8e70,0xce}, + {0x8e71,0x33}, + {0x8e72,0xce}, + {0x8e73,0xd8}, + {0x8e74,0xf9}, + {0x8e75,0x12}, + {0x8e76,0x0e}, + {0x8e77,0xa4}, + {0x8e78,0xe4}, + {0x8e79,0xf5}, + {0x8e7a,0x66}, + {0x8e7b,0xf5}, + {0x8e7c,0x66}, + {0x8e7d,0xe5}, + {0x8e7e,0x66}, + {0x8e7f,0xd3}, + {0x8e80,0x95}, + {0x8e81,0x7b}, + {0x8e82,0x50}, + {0x8e83,0x15}, + {0x8e84,0xaf}, + {0x8e85,0x66}, + {0x8e86,0xe5}, + {0x8e87,0x49}, + {0x8e88,0x2f}, + {0x8e89,0x12}, + {0x8e8a,0x02}, + {0x8e8b,0x4f}, + {0x8e8c,0x93}, + {0x8e8d,0xc3}, + {0x8e8e,0x95}, + {0x8e8f,0x68}, + {0x8e90,0xe4}, + {0x8e91,0x95}, + {0x8e92,0x67}, + {0x8e93,0x50}, + {0x8e94,0x04}, + {0x8e95,0x05}, + {0x8e96,0x66}, + {0x8e97,0x80}, + {0x8e98,0xe4}, + {0x8e99,0x85}, + {0x8e9a,0x66}, + {0x8e9b,0x7c}, + {0x8e9c,0x90}, + {0x8e9d,0x30}, + {0x8e9e,0x25}, + {0x8e9f,0xe4}, + {0x8ea0,0xf0}, + {0x8ea1,0xd2}, + {0x8ea2,0x34}, + {0x8ea3,0x22}, + {0x8ea4,0xf5}, + {0x8ea5,0x68}, + {0x8ea6,0x8e}, + {0x8ea7,0x67}, + {0x8ea8,0x85}, + {0x8ea9,0x67}, + {0x8eaa,0x10}, + {0x8eab,0x85}, + {0x8eac,0x68}, + {0x8ead,0x11}, + {0x8eae,0x12}, + {0x8eaf,0x0a}, + {0x8eb0,0x1b}, + {0x8eb1,0x22}, + {0x8eb2,0x12}, + {0x8eb3,0x02}, + {0x8eb4,0x85}, + {0x8eb5,0xb5}, + {0x8eb6,0x07}, + {0x8eb7,0x03}, + {0x8eb8,0xd3}, + {0x8eb9,0x80}, + {0x8eba,0x01}, + {0x8ebb,0xc3}, + {0x8ebc,0x40}, + {0x8ebd,0x03}, + {0x8ebe,0x02}, + {0x8ebf,0x0f}, + {0x8ec0,0x51}, + {0x8ec1,0x90}, + {0x8ec2,0x30}, + {0x8ec3,0x04}, + {0x8ec4,0xe0}, + {0x8ec5,0x44}, + {0x8ec6,0x20}, + {0x8ec7,0xf0}, + {0x8ec8,0xa3}, + {0x8ec9,0xe0}, + {0x8eca,0x44}, + {0x8ecb,0x40}, + {0x8ecc,0xf0}, + {0x8ecd,0x90}, + {0x8ece,0x50}, + {0x8ecf,0x25}, + {0x8ed0,0xe0}, + {0x8ed1,0x44}, + {0x8ed2,0x04}, + {0x8ed3,0xf0}, + {0x8ed4,0x90}, + {0x8ed5,0x50}, + {0x8ed6,0x03}, + {0x8ed7,0xe0}, + {0x8ed8,0x54}, + {0x8ed9,0xfd}, + {0x8eda,0xf0}, + {0x8edb,0x90}, + {0x8edc,0x50}, + {0x8edd,0x27}, + {0x8ede,0xe0}, + {0x8edf,0x44}, + {0x8ee0,0x01}, + {0x8ee1,0xf0}, + {0x8ee2,0x90}, + {0x8ee3,0x50}, + {0x8ee4,0x31}, + {0x8ee5,0xe4}, + {0x8ee6,0xf0}, + {0x8ee7,0x90}, + {0x8ee8,0x50}, + {0x8ee9,0x33}, + {0x8eea,0xf0}, + {0x8eeb,0x90}, + {0x8eec,0x30}, + {0x8eed,0x1e}, + {0x8eee,0x12}, + {0x8eef,0x01}, + {0x8ef0,0xfb}, + {0x8ef1,0x90}, + {0x8ef2,0x30}, + {0x8ef3,0x18}, + {0x8ef4,0x12}, + {0x8ef5,0x01}, + {0x8ef6,0xfb}, + {0x8ef7,0x90}, + {0x8ef8,0x30}, + {0x8ef9,0x1b}, + {0x8efa,0x12}, + {0x8efb,0x01}, + {0x8efc,0xfb}, + {0x8efd,0xe0}, + {0x8efe,0xf5}, + {0x8eff,0x25}, + {0x8f00,0x90}, + {0x8f01,0x30}, + {0x8f02,0x18}, + {0x8f03,0xe0}, + {0x8f04,0xf5}, + {0x8f05,0x21}, + {0x8f06,0x90}, + {0x8f07,0x60}, + {0x8f08,0x00}, + {0x8f09,0x74}, + {0x8f0a,0xf5}, + {0x8f0b,0xf0}, + {0x8f0c,0x90}, + {0x8f0d,0x3f}, + {0x8f0e,0x01}, + {0x8f0f,0xe4}, + {0x8f10,0xf0}, + {0x8f11,0xa3}, + {0x8f12,0xf0}, + {0x8f13,0x90}, + {0x8f14,0x3f}, + {0x8f15,0x01}, + {0x8f16,0xe0}, + {0x8f17,0x44}, + {0x8f18,0x08}, + {0x8f19,0xf0}, + {0x8f1a,0xe0}, + {0x8f1b,0x44}, + {0x8f1c,0x20}, + {0x8f1d,0xf0}, + {0x8f1e,0x90}, + {0x8f1f,0x3f}, + {0x8f20,0x05}, + {0x8f21,0x74}, + {0x8f22,0x30}, + {0x8f23,0xf0}, + {0x8f24,0xa3}, + {0x8f25,0x74}, + {0x8f26,0x24}, + {0x8f27,0xf0}, + {0x8f28,0x90}, + {0x8f29,0x3f}, + {0x8f2a,0x0b}, + {0x8f2b,0xe0}, + {0x8f2c,0x44}, + {0x8f2d,0x0f}, + {0x8f2e,0xf0}, + {0x8f2f,0x90}, + {0x8f30,0x3f}, + {0x8f31,0x01}, + {0x8f32,0xe0}, + {0x8f33,0x44}, + {0x8f34,0x02}, + {0x8f35,0xf0}, + {0x8f36,0xc2}, + {0x8f37,0x8c}, + {0x8f38,0x75}, + {0x8f39,0x89}, + {0x8f3a,0x03}, + {0x8f3b,0x75}, + {0x8f3c,0xa8}, + {0x8f3d,0x07}, + {0x8f3e,0x75}, + {0x8f3f,0xb8}, + {0x8f40,0x04}, + {0x8f41,0xe4}, + {0x8f42,0xf5}, + {0x8f43,0xd8}, + {0x8f44,0xf5}, + {0x8f45,0xe8}, + {0x8f46,0x90}, + {0x8f47,0x30}, + {0x8f48,0x01}, + {0x8f49,0xe0}, + {0x8f4a,0x44}, + {0x8f4b,0x40}, + {0x8f4c,0xf0}, + {0x8f4d,0xe0}, + {0x8f4e,0x54}, + {0x8f4f,0xbf}, + {0x8f50,0xf0}, + {0x8f51,0x22}, + {0x8f52,0xe5}, + {0x8f53,0x0c}, + {0x8f54,0xd3}, + {0x8f55,0x95}, + {0x8f56,0x7b}, + {0x8f57,0x40}, + {0x8f58,0x01}, + {0x8f59,0x22}, + {0x8f5a,0xe5}, + {0x8f5b,0x49}, + {0x8f5c,0x25}, + {0x8f5d,0x0c}, + {0x8f5e,0x12}, + {0x8f5f,0x02}, + {0x8f60,0x4f}, + {0x8f61,0x93}, + {0x8f62,0x75}, + {0x8f63,0x0d}, + {0x8f64,0x00}, + {0x8f65,0xf5}, + {0x8f66,0x0e}, + {0x8f67,0x45}, + {0x8f68,0x0d}, + {0x8f69,0x70}, + {0x8f6a,0x05}, + {0x8f6b,0x85}, + {0x8f6c,0x64}, + {0x8f6d,0x0f}, + {0x8f6e,0x80}, + {0x8f6f,0x1b}, + {0x8f70,0x12}, + {0x8f71,0x02}, + {0x8f72,0x9b}, + {0x8f73,0xc3}, + {0x8f74,0x33}, + {0x8f75,0xce}, + {0x8f76,0x33}, + {0x8f77,0xce}, + {0x8f78,0xd8}, + {0x8f79,0xf9}, + {0x8f7a,0xf5}, + {0x8f7b,0x0e}, + {0x8f7c,0x8e}, + {0x8f7d,0x0d}, + {0x8f7e,0x85}, + {0x8f7f,0x0d}, + {0x8f80,0x10}, + {0x8f81,0xf5}, + {0x8f82,0x11}, + {0x8f83,0x12}, + {0x8f84,0x0a}, + {0x8f85,0x1b}, + {0x8f86,0x30}, + {0x8f87,0x33}, + {0x8f88,0x63}, + {0x8f89,0xc3}, + {0x8f8a,0x22}, + {0x8f8b,0xe5}, + {0x8f8c,0x0f}, + {0x8f8d,0xd3}, + {0x8f8e,0x94}, + {0x8f8f,0x10}, + {0x8f90,0x40}, + {0x8f91,0x33}, + {0x8f92,0xe5}, + {0x8f93,0x0f}, + {0x8f94,0xd3}, + {0x8f95,0x94}, + {0x8f96,0x60}, + {0x8f97,0x40}, + {0x8f98,0x05}, + {0x8f99,0x75}, + {0x8f9a,0x0f}, + {0x8f9b,0x58}, + {0x8f9c,0x80}, + {0x8f9d,0x11}, + {0x8f9e,0xe5}, + {0x8f9f,0x0f}, + {0x8fa0,0xd3}, + {0x8fa1,0x94}, + {0x8fa2,0x40}, + {0x8fa3,0x40}, + {0x8fa4,0x04}, + {0x8fa5,0x74}, + {0x8fa6,0xf0}, + {0x8fa7,0x80}, + {0x8fa8,0x02}, + {0x8fa9,0x74}, + {0x8faa,0xf8}, + {0x8fab,0x25}, + {0x8fac,0x0f}, + {0x8fad,0xf5}, + {0x8fae,0x0f}, + {0x8faf,0x75}, + {0x8fb0,0x0d}, + {0x8fb1,0x00}, + {0x8fb2,0x85}, + {0x8fb3,0x0f}, + {0x8fb4,0x0e}, + {0x8fb5,0x12}, + {0x8fb6,0x02}, + {0x8fb7,0x9b}, + {0x8fb8,0xc3}, + {0x8fb9,0x33}, + {0x8fba,0xce}, + {0x8fbb,0x33}, + {0x8fbc,0xce}, + {0x8fbd,0xd8}, + {0x8fbe,0xf9}, + {0x8fbf,0xf5}, + {0x8fc0,0x0e}, + {0x8fc1,0x8e}, + {0x8fc2,0x0d}, + {0x8fc3,0x80}, + {0x8fc4,0x0a}, + {0x8fc5,0xe4}, + {0x8fc6,0xf5}, + {0x8fc7,0x0f}, + {0x8fc8,0x75}, + {0x8fc9,0x0d}, + {0x8fca,0x80}, + {0x8fcb,0xf5}, + {0x8fcc,0x0e}, + {0x8fcd,0xf5}, + {0x8fce,0x64}, + {0x8fcf,0x85}, + {0x8fd0,0x0d}, + {0x8fd1,0x10}, + {0x8fd2,0x85}, + {0x8fd3,0x0e}, + {0x8fd4,0x11}, + {0x8fd5,0x12}, + {0x8fd6,0x0a}, + {0x8fd7,0x1b}, + {0x8fd8,0x30}, + {0x8fd9,0x33}, + {0x8fda,0x02}, + {0x8fdb,0xc3}, + {0x8fdc,0x22}, + {0x8fdd,0xe5}, + {0x8fde,0x0f}, + {0x8fdf,0x60}, + {0x8fe0,0x0b}, + {0x8fe1,0x75}, + {0x8fe2,0x10}, + {0x8fe3,0x00}, + {0x8fe4,0x75}, + {0x8fe5,0x11}, + {0x8fe6,0x32}, + {0x8fe7,0x12}, + {0x8fe8,0x16}, + {0x8fe9,0x3d}, + {0x8fea,0x80}, + {0x8feb,0x9f}, + {0x8fec,0x85}, + {0x8fed,0x0c}, + {0x8fee,0x7c}, + {0x8fef,0xd3}, + {0x8ff0,0x22}, + {0x8ff1,0x30}, + {0x8ff2,0x3e}, + {0x8ff3,0x09}, + {0x8ff4,0x30}, + {0x8ff5,0x20}, + {0x8ff6,0x06}, + {0x8ff7,0xae}, + {0x8ff8,0x56}, + {0x8ff9,0xaf}, + {0x8ffa,0x57}, + {0x8ffb,0x80}, + {0x8ffc,0x04}, + {0x8ffd,0xae}, + {0x8ffe,0x69}, + {0x8fff,0xaf}, + {0x9000,0x6a}, + {0x9001,0x8e}, + {0x9002,0x56}, + {0x9003,0x8f}, + {0x9004,0x57}, + {0x9005,0x30}, + {0x9006,0x3e}, + {0x9007,0x09}, + {0x9008,0x30}, + {0x9009,0x21}, + {0x900a,0x06}, + {0x900b,0xae}, + {0x900c,0x58}, + {0x900d,0xaf}, + {0x900e,0x59}, + {0x900f,0x80}, + {0x9010,0x04}, + {0x9011,0xae}, + {0x9012,0x6b}, + {0x9013,0xaf}, + {0x9014,0x6c}, + {0x9015,0x8e}, + {0x9016,0x58}, + {0x9017,0x8f}, + {0x9018,0x59}, + {0x9019,0x30}, + {0x901a,0x3e}, + {0x901b,0x09}, + {0x901c,0x30}, + {0x901d,0x22}, + {0x901e,0x06}, + {0x901f,0xae}, + {0x9020,0x5a}, + {0x9021,0xaf}, + {0x9022,0x5b}, + {0x9023,0x80}, + {0x9024,0x04}, + {0x9025,0xae}, + {0x9026,0x6d}, + {0x9027,0xaf}, + {0x9028,0x6e}, + {0x9029,0x8e}, + {0x902a,0x5a}, + {0x902b,0x8f}, + {0x902c,0x5b}, + {0x902d,0x30}, + {0x902e,0x3e}, + {0x902f,0x09}, + {0x9030,0x30}, + {0x9031,0x23}, + {0x9032,0x06}, + {0x9033,0xae}, + {0x9034,0x5c}, + {0x9035,0xaf}, + {0x9036,0x5d}, + {0x9037,0x80}, + {0x9038,0x04}, + {0x9039,0xae}, + {0x903a,0x6f}, + {0x903b,0xaf}, + {0x903c,0x70}, + {0x903d,0x8e}, + {0x903e,0x5c}, + {0x903f,0x8f}, + {0x9040,0x5d}, + {0x9041,0x30}, + {0x9042,0x3e}, + {0x9043,0x09}, + {0x9044,0x30}, + {0x9045,0x24}, + {0x9046,0x06}, + {0x9047,0xae}, + {0x9048,0x5e}, + {0x9049,0xaf}, + {0x904a,0x5f}, + {0x904b,0x80}, + {0x904c,0x04}, + {0x904d,0xae}, + {0x904e,0x71}, + {0x904f,0xaf}, + {0x9050,0x72}, + {0x9051,0x8e}, + {0x9052,0x5e}, + {0x9053,0x8f}, + {0x9054,0x5f}, + {0x9055,0x30}, + {0x9056,0x3e}, + {0x9057,0x09}, + {0x9058,0x30}, + {0x9059,0x25}, + {0x905a,0x06}, + {0x905b,0xae}, + {0x905c,0x60}, + {0x905d,0xaf}, + {0x905e,0x61}, + {0x905f,0x80}, + {0x9060,0x04}, + {0x9061,0xae}, + {0x9062,0x73}, + {0x9063,0xaf}, + {0x9064,0x74}, + {0x9065,0x8e}, + {0x9066,0x60}, + {0x9067,0x8f}, + {0x9068,0x61}, + {0x9069,0x30}, + {0x906a,0x3e}, + {0x906b,0x09}, + {0x906c,0x30}, + {0x906d,0x26}, + {0x906e,0x06}, + {0x906f,0xae}, + {0x9070,0x62}, + {0x9071,0xaf}, + {0x9072,0x63}, + {0x9073,0x80}, + {0x9074,0x04}, + {0x9075,0xae}, + {0x9076,0x75}, + {0x9077,0xaf}, + {0x9078,0x76}, + {0x9079,0x8e}, + {0x907a,0x62}, + {0x907b,0x8f}, + {0x907c,0x63}, + {0x907d,0x22}, + {0x907e,0x30}, + {0x907f,0x36}, + {0x9080,0x4e}, + {0x9081,0x12}, + {0x9082,0x10}, + {0x9083,0xf6}, + {0x9084,0xe5}, + {0x9085,0x32}, + {0x9086,0xd3}, + {0x9087,0x95}, + {0x9088,0x7c}, + {0x9089,0x40}, + {0x908a,0x0c}, + {0x908b,0xe5}, + {0x908c,0x32}, + {0x908d,0x04}, + {0x908e,0xf5}, + {0x908f,0x0c}, + {0x9090,0x12}, + {0x9091,0x0f}, + {0x9092,0x52}, + {0x9093,0xd2}, + {0x9094,0x37}, + {0x9095,0x80}, + {0x9096,0x44}, + {0x9097,0xe5}, + {0x9098,0x7b}, + {0x9099,0xb5}, + {0x909a,0x7c}, + {0x909b,0x04}, + {0x909c,0x7f}, + {0x909d,0x01}, + {0x909e,0x80}, + {0x909f,0x02}, + {0x90a0,0x7f}, + {0x90a1,0x00}, + {0x90a2,0xef}, + {0x90a3,0x24}, + {0x90a4,0xfb}, + {0x90a5,0xd3}, + {0x90a6,0x64}, + {0x90a7,0x80}, + {0x90a8,0xf8}, + {0x90a9,0xe5}, + {0x90aa,0x7c}, + {0x90ab,0x64}, + {0x90ac,0x80}, + {0x90ad,0x98}, + {0x90ae,0x40}, + {0x90af,0x12}, + {0x90b0,0xc2}, + {0x90b1,0x37}, + {0x90b2,0xe5}, + {0x90b3,0x7b}, + {0x90b4,0xb5}, + {0x90b5,0x7c}, + {0x90b6,0x04}, + {0x90b7,0x7f}, + {0x90b8,0x01}, + {0x90b9,0x80}, + {0x90ba,0x02}, + {0x90bb,0x7f}, + {0x90bc,0x00}, + {0x90bd,0xef}, + {0x90be,0x24}, + {0x90bf,0xfa}, + {0x90c0,0x80}, + {0x90c1,0x06}, + {0x90c2,0xd2}, + {0x90c3,0x37}, + {0x90c4,0xe5}, + {0x90c5,0x7c}, + {0x90c6,0x24}, + {0x90c7,0x02}, + {0x90c8,0xf5}, + {0x90c9,0x0c}, + {0x90ca,0x12}, + {0x90cb,0x0f}, + {0x90cc,0x52}, + {0x90cd,0x80}, + {0x90ce,0x0c}, + {0x90cf,0xe5}, + {0x90d0,0x7c}, + {0x90d1,0x70}, + {0x90d2,0x0f}, + {0x90d3,0x12}, + {0x90d4,0x10}, + {0x90d5,0xf6}, + {0x90d6,0xc2}, + {0x90d7,0x03}, + {0x90d8,0x12}, + {0x90d9,0x16}, + {0x90da,0xa4}, + {0x90db,0xd2}, + {0x90dc,0x02}, + {0x90dd,0xd2}, + {0x90de,0x01}, + {0x90df,0xd2}, + {0x90e0,0x00}, + {0x90e1,0x22}, + {0x90e2,0x30}, + {0x90e3,0x03}, + {0x90e4,0x08}, + {0x90e5,0xc2}, + {0x90e6,0x03}, + {0x90e7,0xc2}, + {0x90e8,0x04}, + {0x90e9,0x12}, + {0x90ea,0x02}, + {0x90eb,0xa5}, + {0x90ec,0x22}, + {0x90ed,0xe4}, + {0x90ee,0xf5}, + {0x90ef,0x0c}, + {0x90f0,0x12}, + {0x90f1,0x0f}, + {0x90f2,0x52}, + {0x90f3,0xd2}, + {0x90f4,0x03}, + {0x90f5,0x22}, + {0x90f6,0x12}, + {0x90f7,0x16}, + {0x90f8,0x90}, + {0x90f9,0xc2}, + {0x90fa,0x3e}, + {0x90fb,0x12}, + {0x90fc,0x0f}, + {0x90fd,0xf1}, + {0x90fe,0xc2}, + {0x90ff,0x3e}, + {0x9100,0x12}, + {0x9101,0x12}, + {0x9102,0xad}, + {0x9103,0x22}, + {0x9104,0xd3}, + {0x9105,0xe5}, + {0x9106,0x57}, + {0x9107,0x95}, + {0x9108,0x6a}, + {0x9109,0xe5}, + {0x910a,0x56}, + {0x910b,0x95}, + {0x910c,0x69}, + {0x910d,0x40}, + {0x910e,0x03}, + {0x910f,0xd3}, + {0x9110,0x80}, + {0x9111,0x01}, + {0x9112,0xc3}, + {0x9113,0x92}, + {0x9114,0x20}, + {0x9115,0xd3}, + {0x9116,0xe5}, + {0x9117,0x59}, + {0x9118,0x95}, + {0x9119,0x6c}, + {0x911a,0xe5}, + {0x911b,0x58}, + {0x911c,0x95}, + {0x911d,0x6b}, + {0x911e,0x40}, + {0x911f,0x03}, + {0x9120,0xd3}, + {0x9121,0x80}, + {0x9122,0x01}, + {0x9123,0xc3}, + {0x9124,0x92}, + {0x9125,0x21}, + {0x9126,0xd3}, + {0x9127,0xe5}, + {0x9128,0x5b}, + {0x9129,0x95}, + {0x912a,0x6e}, + {0x912b,0xe5}, + {0x912c,0x5a}, + {0x912d,0x95}, + {0x912e,0x6d}, + {0x912f,0x40}, + {0x9130,0x03}, + {0x9131,0xd3}, + {0x9132,0x80}, + {0x9133,0x01}, + {0x9134,0xc3}, + {0x9135,0x92}, + {0x9136,0x22}, + {0x9137,0xd3}, + {0x9138,0xe5}, + {0x9139,0x5d}, + {0x913a,0x95}, + {0x913b,0x70}, + {0x913c,0xe5}, + {0x913d,0x5c}, + {0x913e,0x95}, + {0x913f,0x6f}, + {0x9140,0x40}, + {0x9141,0x03}, + {0x9142,0xd3}, + {0x9143,0x80}, + {0x9144,0x01}, + {0x9145,0xc3}, + {0x9146,0x92}, + {0x9147,0x23}, + {0x9148,0xd3}, + {0x9149,0xe5}, + {0x914a,0x5f}, + {0x914b,0x95}, + {0x914c,0x72}, + {0x914d,0xe5}, + {0x914e,0x5e}, + {0x914f,0x95}, + {0x9150,0x71}, + {0x9151,0x40}, + {0x9152,0x03}, + {0x9153,0xd3}, + {0x9154,0x80}, + {0x9155,0x01}, + {0x9156,0xc3}, + {0x9157,0x92}, + {0x9158,0x24}, + {0x9159,0xd3}, + {0x915a,0xe5}, + {0x915b,0x61}, + {0x915c,0x95}, + {0x915d,0x74}, + {0x915e,0xe5}, + {0x915f,0x60}, + {0x9160,0x95}, + {0x9161,0x73}, + {0x9162,0x40}, + {0x9163,0x03}, + {0x9164,0xd3}, + {0x9165,0x80}, + {0x9166,0x01}, + {0x9167,0xc3}, + {0x9168,0x92}, + {0x9169,0x25}, + {0x916a,0xd3}, + {0x916b,0xe5}, + {0x916c,0x63}, + {0x916d,0x95}, + {0x916e,0x76}, + {0x916f,0xe5}, + {0x9170,0x62}, + {0x9171,0x95}, + {0x9172,0x75}, + {0x9173,0x40}, + {0x9174,0x03}, + {0x9175,0xd3}, + {0x9176,0x80}, + {0x9177,0x01}, + {0x9178,0xc3}, + {0x9179,0x92}, + {0x917a,0x26}, + {0x917b,0x22}, + {0x917c,0x12}, + {0x917d,0x11}, + {0x917e,0x04}, + {0x917f,0x30}, + {0x9180,0x36}, + {0x9181,0x40}, + {0x9182,0xe5}, + {0x9183,0x24}, + {0x9184,0x54}, + {0x9185,0x1f}, + {0x9186,0xff}, + {0x9187,0x60}, + {0x9188,0x0e}, + {0x9189,0x64}, + {0x918a,0x1f}, + {0x918b,0x60}, + {0x918c,0x0a}, + {0x918d,0xe5}, + {0x918e,0x7b}, + {0x918f,0x65}, + {0x9190,0x7c}, + {0x9191,0x60}, + {0x9192,0x04}, + {0x9193,0xe5}, + {0x9194,0x7c}, + {0x9195,0x70}, + {0x9196,0x18}, + {0x9197,0xbf}, + {0x9198,0x1f}, + {0x9199,0x02}, + {0x919a,0xb2}, + {0x919b,0x37}, + {0x919c,0xe5}, + {0x919d,0x7b}, + {0x919e,0xb5}, + {0x919f,0x7c}, + {0x91a0,0x02}, + {0x91a1,0xc2}, + {0x91a2,0x37}, + {0x91a3,0xe5}, + {0x91a4,0x7c}, + {0x91a5,0x70}, + {0x91a6,0x02}, + {0x91a7,0xd2}, + {0x91a8,0x37}, + {0x91a9,0xc2}, + {0x91aa,0x02}, + {0x91ab,0xd2}, + {0x91ac,0x01}, + {0x91ad,0xd2}, + {0x91ae,0x00}, + {0x91af,0xc2}, + {0x91b0,0x3e}, + {0x91b1,0x12}, + {0x91b2,0x0f}, + {0x91b3,0xf1}, + {0x91b4,0xc2}, + {0x91b5,0x3e}, + {0x91b6,0x12}, + {0x91b7,0x12}, + {0x91b8,0xad}, + {0x91b9,0x30}, + {0x91ba,0x37}, + {0x91bb,0x03}, + {0x91bc,0x02}, + {0x91bd,0x16}, + {0x91be,0xa4}, + {0x91bf,0x02}, + {0x91c0,0x16}, + {0x91c1,0xb5}, + {0x91c2,0xd2}, + {0x91c3,0x3e}, + {0x91c4,0x12}, + {0x91c5,0x0f}, + {0x91c6,0xf1}, + {0x91c7,0xd2}, + {0x91c8,0x3e}, + {0x91c9,0x12}, + {0x91ca,0x12}, + {0x91cb,0xad}, + {0x91cc,0x12}, + {0x91cd,0x16}, + {0x91ce,0xa4}, + {0x91cf,0xe5}, + {0x91d0,0x32}, + {0x91d1,0xd3}, + {0x91d2,0x95}, + {0x91d3,0x7c}, + {0x91d4,0x40}, + {0x91d5,0x05}, + {0x91d6,0xe4}, + {0x91d7,0x95}, + {0x91d8,0x7c}, + {0x91d9,0x40}, + {0x91da,0x06}, + {0x91db,0xc2}, + {0x91dc,0x02}, + {0x91dd,0xd2}, + {0x91de,0x01}, + {0x91df,0xd2}, + {0x91e0,0x00}, + {0x91e1,0x22}, + {0x91e2,0x12}, + {0x91e3,0x11}, + {0x91e4,0x04}, + {0x91e5,0xc3}, + {0x91e6,0x30}, + {0x91e7,0x25}, + {0x91e8,0x0c}, + {0x91e9,0xe5}, + {0x91ea,0x61}, + {0x91eb,0x95}, + {0x91ec,0x74}, + {0x91ed,0xff}, + {0x91ee,0xe5}, + {0x91ef,0x60}, + {0x91f0,0x95}, + {0x91f1,0x73}, + {0x91f2,0xfe}, + {0x91f3,0x80}, + {0x91f4,0x0a}, + {0x91f5,0xe5}, + {0x91f6,0x74}, + {0x91f7,0x95}, + {0x91f8,0x61}, + {0x91f9,0xff}, + {0x91fa,0xe5}, + {0x91fb,0x73}, + {0x91fc,0x95}, + {0x91fd,0x60}, + {0x91fe,0xfe}, + {0x91ff,0x8e}, + {0x9200,0x0a}, + {0x9201,0x8f}, + {0x9202,0x0b}, + {0x9203,0x30}, + {0x9204,0x03}, + {0x9205,0x26}, + {0x9206,0x12}, + {0x9207,0x02}, + {0x9208,0xb3}, + {0x9209,0x50}, + {0x920a,0x03}, + {0x920b,0x30}, + {0x920c,0x27}, + {0x920d,0x07}, + {0x920e,0xc2}, + {0x920f,0x3e}, + {0x9210,0x12}, + {0x9211,0x0f}, + {0x9212,0xf1}, + {0x9213,0x80}, + {0x9214,0x2f}, + {0x9215,0x05}, + {0x9216,0x31}, + {0x9217,0xe5}, + {0x9218,0x31}, + {0x9219,0xd3}, + {0x921a,0x94}, + {0x921b,0x02}, + {0x921c,0x40}, + {0x921d,0x29}, + {0x921e,0xe4}, + {0x921f,0xf5}, + {0x9220,0x31}, + {0x9221,0xc2}, + {0x9222,0x03}, + {0x9223,0xc2}, + {0x9224,0x02}, + {0x9225,0xc2}, + {0x9226,0x01}, + {0x9227,0xd2}, + {0x9228,0x00}, + {0x9229,0xd2}, + {0x922a,0x34}, + {0x922b,0x22}, + {0x922c,0x12}, + {0x922d,0x02}, + {0x922e,0xb3}, + {0x922f,0x50}, + {0x9230,0x03}, + {0x9231,0x30}, + {0x9232,0x27}, + {0x9233,0x04}, + {0x9234,0x05}, + {0x9235,0x31}, + {0x9236,0x80}, + {0x9237,0x03}, + {0x9238,0xe4}, + {0x9239,0xf5}, + {0x923a,0x31}, + {0x923b,0xe5}, + {0x923c,0x31}, + {0x923d,0xd3}, + {0x923e,0x94}, + {0x923f,0x02}, + {0x9240,0x40}, + {0x9241,0x05}, + {0x9242,0xd2}, + {0x9243,0x03}, + {0x9244,0xe4}, + {0x9245,0xf5}, + {0x9246,0x31}, + {0x9247,0x22}, + {0x9248,0xe5}, + {0x9249,0x0a}, + {0x924a,0x70}, + {0x924b,0x04}, + {0x924c,0x7a}, + {0x924d,0x13}, + {0x924e,0x7b}, + {0x924f,0x81}, + {0x9250,0xe5}, + {0x9251,0x0a}, + {0x9252,0xb4}, + {0x9253,0x01}, + {0x9254,0x04}, + {0x9255,0x7a}, + {0x9256,0x13}, + {0x9257,0x7b}, + {0x9258,0x95}, + {0x9259,0xe5}, + {0x925a,0x0a}, + {0x925b,0xb4}, + {0x925c,0x02}, + {0x925d,0x04}, + {0x925e,0x7a}, + {0x925f,0x13}, + {0x9260,0x7b}, + {0x9261,0xa9}, + {0x9262,0x8b}, + {0x9263,0x82}, + {0x9264,0x8a}, + {0x9265,0x83}, + {0x9266,0x12}, + {0x9267,0x09}, + {0x9268,0xe5}, + {0x9269,0x8f}, + {0x926a,0x37}, + {0x926b,0x8e}, + {0x926c,0x36}, + {0x926d,0x8d}, + {0x926e,0x35}, + {0x926f,0x8c}, + {0x9270,0x34}, + {0x9271,0xe5}, + {0x9272,0x82}, + {0x9273,0x24}, + {0x9274,0x04}, + {0x9275,0xf5}, + {0x9276,0x82}, + {0x9277,0xe4}, + {0x9278,0x35}, + {0x9279,0x83}, + {0x927a,0xf5}, + {0x927b,0x83}, + {0x927c,0x12}, + {0x927d,0x09}, + {0x927e,0xe5}, + {0x927f,0x8f}, + {0x9280,0x3b}, + {0x9281,0x8e}, + {0x9282,0x3a}, + {0x9283,0x8d}, + {0x9284,0x39}, + {0x9285,0x8c}, + {0x9286,0x38}, + {0x9287,0xeb}, + {0x9288,0x24}, + {0x9289,0x08}, + {0x928a,0x12}, + {0x928b,0x02}, + {0x928c,0x2f}, + {0x928d,0x12}, + {0x928e,0x01}, + {0x928f,0x97}, + {0x9290,0xeb}, + {0x9291,0x24}, + {0x9292,0x0c}, + {0x9293,0x12}, + {0x9294,0x02}, + {0x9295,0x2f}, + {0x9296,0x8f}, + {0x9297,0x43}, + {0x9298,0x8e}, + {0x9299,0x42}, + {0x929a,0x8d}, + {0x929b,0x41}, + {0x929c,0x8c}, + {0x929d,0x40}, + {0x929e,0xeb}, + {0x929f,0x24}, + {0x92a0,0x10}, + {0x92a1,0x12}, + {0x92a2,0x02}, + {0x92a3,0x2f}, + {0x92a4,0x8f}, + {0x92a5,0x47}, + {0x92a6,0x8e}, + {0x92a7,0x46}, + {0x92a8,0x8d}, + {0x92a9,0x45}, + {0x92aa,0x8c}, + {0x92ab,0x44}, + {0x92ac,0x22}, + {0x92ad,0x30}, + {0x92ae,0x3e}, + {0x92af,0x07}, + {0x92b0,0x30}, + {0x92b1,0x20}, + {0x92b2,0x04}, + {0x92b3,0xaf}, + {0x92b4,0x4a}, + {0x92b5,0x80}, + {0x92b6,0x02}, + {0x92b7,0xaf}, + {0x92b8,0x7c}, + {0x92b9,0x8f}, + {0x92ba,0x4a}, + {0x92bb,0x30}, + {0x92bc,0x3e}, + {0x92bd,0x07}, + {0x92be,0x30}, + {0x92bf,0x21}, + {0x92c0,0x04}, + {0x92c1,0xaf}, + {0x92c2,0x4b}, + {0x92c3,0x80}, + {0x92c4,0x02}, + {0x92c5,0xaf}, + {0x92c6,0x7c}, + {0x92c7,0x8f}, + {0x92c8,0x4b}, + {0x92c9,0x30}, + {0x92ca,0x3e}, + {0x92cb,0x07}, + {0x92cc,0x30}, + {0x92cd,0x22}, + {0x92ce,0x04}, + {0x92cf,0xaf}, + {0x92d0,0x4c}, + {0x92d1,0x80}, + {0x92d2,0x02}, + {0x92d3,0xaf}, + {0x92d4,0x7c}, + {0x92d5,0x8f}, + {0x92d6,0x4c}, + {0x92d7,0x30}, + {0x92d8,0x3e}, + {0x92d9,0x07}, + {0x92da,0x30}, + {0x92db,0x23}, + {0x92dc,0x04}, + {0x92dd,0xaf}, + {0x92de,0x4d}, + {0x92df,0x80}, + {0x92e0,0x02}, + {0x92e1,0xaf}, + {0x92e2,0x7c}, + {0x92e3,0x8f}, + {0x92e4,0x4d}, + {0x92e5,0x30}, + {0x92e6,0x3e}, + {0x92e7,0x07}, + {0x92e8,0x30}, + {0x92e9,0x24}, + {0x92ea,0x04}, + {0x92eb,0xaf}, + {0x92ec,0x4e}, + {0x92ed,0x80}, + {0x92ee,0x02}, + {0x92ef,0xaf}, + {0x92f0,0x7c}, + {0x92f1,0x8f}, + {0x92f2,0x4e}, + {0x92f3,0x30}, + {0x92f4,0x3e}, + {0x92f5,0x07}, + {0x92f6,0x30}, + {0x92f7,0x25}, + {0x92f8,0x04}, + {0x92f9,0xaf}, + {0x92fa,0x4f}, + {0x92fb,0x80}, + {0x92fc,0x02}, + {0x92fd,0xaf}, + {0x92fe,0x7c}, + {0x92ff,0x8f}, + {0x9300,0x4f}, + {0x9301,0x30}, + {0x9302,0x3e}, + {0x9303,0x07}, + {0x9304,0x30}, + {0x9305,0x26}, + {0x9306,0x04}, + {0x9307,0xaf}, + {0x9308,0x50}, + {0x9309,0x80}, + {0x930a,0x02}, + {0x930b,0xaf}, + {0x930c,0x7c}, + {0x930d,0x8f}, + {0x930e,0x50}, + {0x930f,0x22}, + {0x9310,0xe5}, + {0x9311,0x7d}, + {0x9312,0x64}, + {0x9313,0x01}, + {0x9314,0x70}, + {0x9315,0x47}, + {0x9316,0xe5}, + {0x9317,0x49}, + {0x9318,0x25}, + {0x9319,0x7c}, + {0x931a,0x12}, + {0x931b,0x01}, + {0x931c,0xa4}, + {0x931d,0xfe}, + {0x931e,0xe4}, + {0x931f,0x8f}, + {0x9320,0x68}, + {0x9321,0x8e}, + {0x9322,0x67}, + {0x9323,0xf5}, + {0x9324,0x66}, + {0x9325,0xf5}, + {0x9326,0x65}, + {0x9327,0x12}, + {0x9328,0x01}, + {0x9329,0xf2}, + {0x932a,0x7b}, + {0x932b,0xff}, + {0x932c,0xfa}, + {0x932d,0xf9}, + {0x932e,0xf8}, + {0x932f,0x12}, + {0x9330,0x01}, + {0x9331,0xe7}, + {0x9332,0xc0}, + {0x9333,0x05}, + {0x9334,0xc0}, + {0x9335,0x06}, + {0x9336,0xc0}, + {0x9337,0x07}, + {0x9338,0x12}, + {0x9339,0x01}, + {0x933a,0xa0}, + {0x933b,0xab}, + {0x933c,0x07}, + {0x933d,0xfa}, + {0x933e,0xe4}, + {0x933f,0xf9}, + {0x9340,0xf8}, + {0x9341,0xd0}, + {0x9342,0x07}, + {0x9343,0xd0}, + {0x9344,0x06}, + {0x9345,0xd0}, + {0x9346,0x05}, + {0x9347,0x12}, + {0x9348,0x02}, + {0x9349,0x6d}, + {0x934a,0x85}, + {0x934b,0x68}, + {0x934c,0x65}, + {0x934d,0x85}, + {0x934e,0x7c}, + {0x934f,0x66}, + {0x9350,0xe5}, + {0x9351,0x49}, + {0x9352,0x25}, + {0x9353,0x7c}, + {0x9354,0x12}, + {0x9355,0x02}, + {0x9356,0x4f}, + {0x9357,0x93}, + {0x9358,0x75}, + {0x9359,0x67}, + {0x935a,0x00}, + {0x935b,0xf5}, + {0x935c,0x68}, + {0x935d,0x90}, + {0x935e,0x50}, + {0x935f,0x82}, + {0x9360,0xe5}, + {0x9361,0x65}, + {0x9362,0xf0}, + {0x9363,0xa3}, + {0x9364,0xe5}, + {0x9365,0x66}, + {0x9366,0xf0}, + {0x9367,0xa3}, + {0x9368,0xe5}, + {0x9369,0x67}, + {0x936a,0xf0}, + {0x936b,0xa3}, + {0x936c,0xe5}, + {0x936d,0x68}, + {0x936e,0xf0}, + {0x936f,0x22}, + {0x9370,0x56}, + {0x9371,0x0c}, + {0x9372,0x04}, + {0x9373,0x00}, + {0x9374,0x2a}, + {0x9375,0x35}, + {0x9376,0x40}, + {0x9377,0x49}, + {0x9378,0x52}, + {0x9379,0x5b}, + {0x937a,0x64}, + {0x937b,0x6d}, + {0x937c,0x76}, + {0x937d,0x7f}, + {0x937e,0x88}, + {0x937f,0x91}, + {0x9380,0x07}, + {0x9381,0x20}, + {0x9382,0x12}, + {0x9383,0x28}, + {0x9384,0x1e}, + {0x9385,0x18}, + {0x9386,0x18}, + {0x9387,0x28}, + {0x9388,0x1e}, + {0x9389,0x18}, + {0x938a,0x12}, + {0x938b,0x28}, + {0x938c,0x1e}, + {0x938d,0x18}, + {0x938e,0x12}, + {0x938f,0x28}, + {0x9390,0x18}, + {0x9391,0x18}, + {0x9392,0x12}, + {0x9393,0x20}, + {0x9394,0x18}, + {0x9395,0x28}, + {0x9396,0x1c}, + {0x9397,0x30}, + {0x9398,0x24}, + {0x9399,0x10}, + {0x939a,0x1c}, + {0x939b,0x18}, + {0x939c,0x24}, + {0x939d,0x1c}, + {0x939e,0x14}, + {0x939f,0x24}, + {0x93a0,0x1c}, + {0x93a1,0x28}, + {0x93a2,0x0c}, + {0x93a3,0x30}, + {0x93a4,0x14}, + {0x93a5,0x10}, + {0x93a6,0x0c}, + {0x93a7,0x18}, + {0x93a8,0x14}, + {0x93a9,0x1c}, + {0x93aa,0x20}, + {0x93ab,0x24}, + {0x93ac,0x28}, + {0x93ad,0x0c}, + {0x93ae,0x14}, + {0x93af,0x14}, + {0x93b0,0x1c}, + {0x93b1,0x1c}, + {0x93b2,0x14}, + {0x93b3,0x24}, + {0x93b4,0x1c}, + {0x93b5,0x2c}, + {0x93b6,0x14}, + {0x93b7,0x34}, + {0x93b8,0x1c}, + {0x93b9,0x1c}, + {0x93ba,0x08}, + {0x93bb,0x24}, + {0x93bc,0x10}, + {0x93bd,0x19}, + {0x93be,0x19}, + {0x93bf,0x1c}, + {0x93c0,0x19}, + {0x93c1,0x19}, + {0x93c2,0x10}, + {0x93c3,0x10}, + {0x93c4,0x10}, + {0x93c5,0x10}, + {0x93c6,0x10}, + {0x93c7,0x00}, + {0x93c8,0x00}, + {0x93c9,0x00}, + {0x93ca,0x00}, + {0x93cb,0x00}, + {0x93cc,0x12}, + {0x93cd,0x11}, + {0x93ce,0x04}, + {0x93cf,0xd2}, + {0x93d0,0x3e}, + {0x93d1,0x12}, + {0x93d2,0x0f}, + {0x93d3,0xf1}, + {0x93d4,0xd2}, + {0x93d5,0x3e}, + {0x93d6,0x12}, + {0x93d7,0x12}, + {0x93d8,0xad}, + {0x93d9,0x30}, + {0x93da,0x36}, + {0x93db,0x26}, + {0x93dc,0x30}, + {0x93dd,0x37}, + {0x93de,0x06}, + {0x93df,0xe5}, + {0x93e0,0x7b}, + {0x93e1,0x65}, + {0x93e2,0x7c}, + {0x93e3,0x60}, + {0x93e4,0x3e}, + {0x93e5,0x20}, + {0x93e6,0x37}, + {0x93e7,0x04}, + {0x93e8,0xe5}, + {0x93e9,0x7c}, + {0x93ea,0x60}, + {0x93eb,0x37}, + {0x93ec,0xe5}, + {0x93ed,0x24}, + {0x93ee,0x54}, + {0x93ef,0x1f}, + {0x93f0,0xff}, + {0x93f1,0xbf}, + {0x93f2,0x1f}, + {0x93f3,0x06}, + {0x93f4,0x30}, + {0x93f5,0x25}, + {0x93f6,0x03}, + {0x93f7,0x20}, + {0x93f8,0x26}, + {0x93f9,0x29}, + {0x93fa,0x30}, + {0x93fb,0x37}, + {0x93fc,0x02}, + {0x93fd,0x80}, + {0x93fe,0x21}, + {0x93ff,0x02}, + {0x9400,0x16}, + {0x9401,0xb5}, + {0x9402,0xe5}, + {0x9403,0x7b}, + {0x9404,0xd3}, + {0x9405,0x95}, + {0x9406,0x7c}, + {0x9407,0x40}, + {0x9408,0x03}, + {0x9409,0xd3}, + {0x940a,0x80}, + {0x940b,0x01}, + {0x940c,0xc3}, + {0x940d,0x50}, + {0x940e,0x14}, + {0x940f,0x20}, + {0x9410,0x39}, + {0x9411,0x0e}, + {0x9412,0xe5}, + {0x9413,0x24}, + {0x9414,0x54}, + {0x9415,0x1f}, + {0x9416,0xff}, + {0x9417,0xbf}, + {0x9418,0x1f}, + {0x9419,0x06}, + {0x941a,0x30}, + {0x941b,0x25}, + {0x941c,0x03}, + {0x941d,0x20}, + {0x941e,0x26}, + {0x941f,0x03}, + {0x9420,0x02}, + {0x9421,0x16}, + {0x9422,0xa4}, + {0x9423,0x12}, + {0x9424,0x02}, + {0x9425,0xc7}, + {0x9426,0x22}, + {0x9427,0xc2}, + {0x9428,0x34}, + {0x9429,0x20}, + {0x942a,0x07}, + {0x942b,0x08}, + {0x942c,0x20}, + {0x942d,0x06}, + {0x942e,0x05}, + {0x942f,0xe4}, + {0x9430,0xf5}, + {0x9431,0x0a}, + {0x9432,0x80}, + {0x9433,0x2b}, + {0x9434,0x20}, + {0x9435,0x07}, + {0x9436,0x08}, + {0x9437,0x30}, + {0x9438,0x06}, + {0x9439,0x05}, + {0x943a,0x75}, + {0x943b,0x0a}, + {0x943c,0x20}, + {0x943d,0x80}, + {0x943e,0x20}, + {0x943f,0x30}, + {0x9440,0x00}, + {0x9441,0x05}, + {0x9442,0x75}, + {0x9443,0x0a}, + {0x9444,0x01}, + {0x9445,0x80}, + {0x9446,0x18}, + {0x9447,0xe5}, + {0x9448,0x20}, + {0x9449,0x54}, + {0x944a,0x07}, + {0x944b,0xff}, + {0x944c,0xbf}, + {0x944d,0x06}, + {0x944e,0x0d}, + {0x944f,0x30}, + {0x9450,0x31}, + {0x9451,0x04}, + {0x9452,0x7f}, + {0x9453,0x12}, + {0x9454,0x80}, + {0x9455,0x02}, + {0x9456,0x7f}, + {0x9457,0x02}, + {0x9458,0x8f}, + {0x9459,0x0a}, + {0x945a,0x80}, + {0x945b,0x03}, + {0x945c,0x75}, + {0x945d,0x0a}, + {0x945e,0xfe}, + {0x945f,0x90}, + {0x9460,0x30}, + {0x9461,0x27}, + {0x9462,0xe5}, + {0x9463,0x0a}, + {0x9464,0xf0}, + {0x9465,0xe5}, + {0x9466,0x23}, + {0x9467,0x54}, + {0x9468,0xf8}, + {0x9469,0xf5}, + {0x946a,0x0a}, + {0x946b,0xe5}, + {0x946c,0x78}, + {0x946d,0x25}, + {0x946e,0x0a}, + {0x946f,0xf5}, + {0x9470,0x0a}, + {0x9471,0x90}, + {0x9472,0x30}, + {0x9473,0x26}, + {0x9474,0xe5}, + {0x9475,0x0a}, + {0x9476,0xf0}, + {0x9477,0x22}, + {0x9478,0xe5}, + {0x9479,0x0a}, + {0x947a,0x70}, + {0x947b,0x04}, + {0x947c,0x7e}, + {0x947d,0x13}, + {0x947e,0x7f}, + {0x947f,0xbd}, + {0x9480,0xe5}, + {0x9481,0x0a}, + {0x9482,0xb4}, + {0x9483,0x01}, + {0x9484,0x04}, + {0x9485,0x7e}, + {0x9486,0x13}, + {0x9487,0x7f}, + {0x9488,0xc2}, + {0x9489,0xe5}, + {0x948a,0x0a}, + {0x948b,0xb4}, + {0x948c,0x02}, + {0x948d,0x04}, + {0x948e,0x7e}, + {0x948f,0x13}, + {0x9490,0x7f}, + {0x9491,0xc7}, + {0x9492,0x8f}, + {0x9493,0x82}, + {0x9494,0x8e}, + {0x9495,0x83}, + {0x9496,0xe4}, + {0x9497,0x93}, + {0x9498,0xf5}, + {0x9499,0x2c}, + {0x949a,0x74}, + {0x949b,0x01}, + {0x949c,0x93}, + {0x949d,0xf5}, + {0x949e,0x2d}, + {0x949f,0x74}, + {0x94a0,0x02}, + {0x94a1,0x93}, + {0x94a2,0xf5}, + {0x94a3,0x2e}, + {0x94a4,0x74}, + {0x94a5,0x03}, + {0x94a6,0x93}, + {0x94a7,0xf5}, + {0x94a8,0x2f}, + {0x94a9,0x74}, + {0x94aa,0x04}, + {0x94ab,0x93}, + {0x94ac,0xf5}, + {0x94ad,0x30}, + {0x94ae,0xe5}, + {0x94af,0x0a}, + {0x94b0,0xb4}, + {0x94b1,0x01}, + {0x94b2,0x07}, + {0x94b3,0x74}, + {0x94b4,0x2c}, + {0x94b5,0x25}, + {0x94b6,0x78}, + {0x94b7,0xf8}, + {0x94b8,0x76}, + {0x94b9,0x40}, + {0x94ba,0xe5}, + {0x94bb,0x0a}, + {0x94bc,0xb4}, + {0x94bd,0x02}, + {0x94be,0x07}, + {0x94bf,0x74}, + {0x94c0,0x2c}, + {0x94c1,0x25}, + {0x94c2,0x78}, + {0x94c3,0xf8}, + {0x94c4,0x76}, + {0x94c5,0x80}, + {0x94c6,0x22}, + {0x94c7,0xc2}, + {0x94c8,0xaf}, + {0x94c9,0x90}, + {0x94ca,0x30}, + {0x94cb,0x27}, + {0x94cc,0x74}, + {0x94cd,0xfa}, + {0x94ce,0xf0}, + {0x94cf,0x12}, + {0x94d0,0x0e}, + {0x94d1,0xb2}, + {0x94d2,0x12}, + {0x94d3,0x16}, + {0x94d4,0x15}, + {0x94d5,0xe4}, + {0x94d6,0xf5}, + {0x94d7,0x33}, + {0x94d8,0xd2}, + {0x94d9,0xaf}, + {0x94da,0x12}, + {0x94db,0x0b}, + {0x94dc,0x67}, + {0x94dd,0x30}, + {0x94de,0x30}, + {0x94df,0x03}, + {0x94e0,0x12}, + {0x94e1,0x07}, + {0x94e2,0x02}, + {0x94e3,0x30}, + {0x94e4,0x34}, + {0x94e5,0x03}, + {0x94e6,0x12}, + {0x94e7,0x14}, + {0x94e8,0x27}, + {0x94e9,0x30}, + {0x94ea,0x3d}, + {0x94eb,0xee}, + {0x94ec,0xc2}, + {0x94ed,0x3d}, + {0x94ee,0xd2}, + {0x94ef,0x35}, + {0x94f0,0x30}, + {0x94f1,0x00}, + {0x94f2,0x05}, + {0x94f3,0x12}, + {0x94f4,0x15}, + {0x94f5,0xe8}, + {0x94f6,0x80}, + {0x94f7,0x17}, + {0x94f8,0x30}, + {0x94f9,0x07}, + {0x94fa,0x0b}, + {0x94fb,0x30}, + {0x94fc,0x06}, + {0x94fd,0x08}, + {0x94fe,0x20}, + {0x94ff,0x31}, + {0x9500,0x0e}, + {0x9501,0x12}, + {0x9502,0x11}, + {0x9503,0xe2}, + {0x9504,0x80}, + {0x9505,0x09}, + {0x9506,0x20}, + {0x9507,0x07}, + {0x9508,0x06}, + {0x9509,0x30}, + {0x950a,0x06}, + {0x950b,0x03}, + {0x950c,0x12}, + {0x950d,0x0d}, + {0x950e,0xb8}, + {0x950f,0xc2}, + {0x9510,0x35}, + {0x9511,0x80}, + {0x9512,0xc7}, + {0x9513,0xc0}, + {0x9514,0xe0}, + {0x9515,0xc0}, + {0x9516,0x83}, + {0x9517,0xc0}, + {0x9518,0x82}, + {0x9519,0xc0}, + {0x951a,0xd0}, + {0x951b,0x90}, + {0x951c,0x3f}, + {0x951d,0x0d}, + {0x951e,0xe0}, + {0x951f,0xf5}, + {0x9520,0x09}, + {0x9521,0xe5}, + {0x9522,0x09}, + {0x9523,0x30}, + {0x9524,0xe0}, + {0x9525,0x2e}, + {0x9526,0xe5}, + {0x9527,0x79}, + {0x9528,0xb4}, + {0x9529,0x01}, + {0x952a,0x09}, + {0x952b,0x90}, + {0x952c,0x3a}, + {0x952d,0x00}, + {0x952e,0xe0}, + {0x952f,0xf5}, + {0x9530,0x77}, + {0x9531,0x44}, + {0x9532,0x01}, + {0x9533,0xf0}, + {0x9534,0xe5}, + {0x9535,0x79}, + {0x9536,0xb4}, + {0x9537,0x03}, + {0x9538,0x09}, + {0x9539,0x90}, + {0x953a,0x3a}, + {0x953b,0x00}, + {0x953c,0xe0}, + {0x953d,0xf5}, + {0x953e,0x77}, + {0x953f,0x54}, + {0x9540,0xfe}, + {0x9541,0xf0}, + {0x9542,0xe5}, + {0x9543,0x79}, + {0x9544,0xb4}, + {0x9545,0x03}, + {0x9546,0x05}, + {0x9547,0x75}, + {0x9548,0x79}, + {0x9549,0x00}, + {0x954a,0x80}, + {0x954b,0x02}, + {0x954c,0x05}, + {0x954d,0x79}, + {0x954e,0x90}, + {0x954f,0x3f}, + {0x9550,0x0d}, + {0x9551,0x74}, + {0x9552,0x01}, + {0x9553,0xf0}, + {0x9554,0xd0}, + {0x9555,0xd0}, + {0x9556,0xd0}, + {0x9557,0x82}, + {0x9558,0xd0}, + {0x9559,0x83}, + {0x955a,0xd0}, + {0x955b,0xe0}, + {0x955c,0x32}, + {0x955d,0x90}, + {0x955e,0x50}, + {0x955f,0x27}, + {0x9560,0xe0}, + {0x9561,0x44}, + {0x9562,0x01}, + {0x9563,0xf0}, + {0x9564,0x90}, + {0x9565,0x50}, + {0x9566,0x34}, + {0x9567,0x74}, + {0x9568,0x80}, + {0x9569,0xf0}, + {0x956a,0xa3}, + {0x956b,0x74}, + {0x956c,0x2a}, + {0x956d,0xf0}, + {0x956e,0xa3}, + {0x956f,0x74}, + {0x9570,0x14}, + {0x9571,0xf0}, + {0x9572,0x90}, + {0x9573,0x50}, + {0x9574,0x30}, + {0x9575,0xe4}, + {0x9576,0xf0}, + {0x9577,0xa3}, + {0x9578,0x74}, + {0x9579,0x02}, + {0x957a,0xf0}, + {0x957b,0xa3}, + {0x957c,0xe4}, + {0x957d,0xf0}, + {0x957e,0xa3}, + {0x957f,0x74}, + {0x9580,0x80}, + {0x9581,0xf0}, + {0x9582,0xe4}, + {0x9583,0xf5}, + {0x9584,0x0a}, + {0x9585,0x12}, + {0x9586,0x12}, + {0x9587,0x48}, + {0x9588,0x75}, + {0x9589,0x78}, + {0x958a,0x02}, + {0x958b,0x75}, + {0x958c,0x0a}, + {0x958d,0x01}, + {0x958e,0x12}, + {0x958f,0x14}, + {0x9590,0x78}, + {0x9591,0xd2}, + {0x9592,0x18}, + {0x9593,0xd2}, + {0x9594,0x19}, + {0x9595,0xc2}, + {0x9596,0x3c}, + {0x9597,0xc2}, + {0x9598,0x3b}, + {0x9599,0xd2}, + {0x959a,0x1a}, + {0x959b,0xd2}, + {0x959c,0x38}, + {0x959d,0xd2}, + {0x959e,0x30}, + {0x959f,0xc2}, + {0x95a0,0x35}, + {0x95a1,0xc2}, + {0x95a2,0x3d}, + {0x95a3,0x22}, + {0x95a4,0x85}, + {0x95a5,0x13}, + {0x95a6,0x14}, + {0x95a7,0x7f}, + {0x95a8,0x08}, + {0x95a9,0xe5}, + {0x95aa,0x14}, + {0x95ab,0x30}, + {0x95ac,0xe7}, + {0x95ad,0x04}, + {0x95ae,0xd2}, + {0x95af,0x29}, + {0x95b0,0x80}, + {0x95b1,0x02}, + {0x95b2,0xc2}, + {0x95b3,0x29}, + {0x95b4,0x12}, + {0x95b5,0x01}, + {0x95b6,0x6c}, + {0x95b7,0x75}, + {0x95b8,0x51}, + {0x95b9,0x0a}, + {0x95ba,0xae}, + {0x95bb,0x51}, + {0x95bc,0x15}, + {0x95bd,0x51}, + {0x95be,0xee}, + {0x95bf,0x70}, + {0x95c0,0xf9}, + {0x95c1,0xe5}, + {0x95c2,0x14}, + {0x95c3,0x25}, + {0x95c4,0xe0}, + {0x95c5,0xf5}, + {0x95c6,0x14}, + {0x95c7,0xd2}, + {0x95c8,0x28}, + {0x95c9,0x12}, + {0x95ca,0x01}, + {0x95cb,0x6c}, + {0x95cc,0x75}, + {0x95cd,0x51}, + {0x95ce,0x0a}, + {0x95cf,0xae}, + {0x95d0,0x51}, + {0x95d1,0x15}, + {0x95d2,0x51}, + {0x95d3,0xee}, + {0x95d4,0x70}, + {0x95d5,0xf9}, + {0x95d6,0xc2}, + {0x95d7,0x28}, + {0x95d8,0x12}, + {0x95d9,0x01}, + {0x95da,0x6c}, + {0x95db,0x75}, + {0x95dc,0x51}, + {0x95dd,0x05}, + {0x95de,0xae}, + {0x95df,0x51}, + {0x95e0,0x15}, + {0x95e1,0x51}, + {0x95e2,0xee}, + {0x95e3,0x70}, + {0x95e4,0xf9}, + {0x95e5,0xdf}, + {0x95e6,0xc2}, + {0x95e7,0x22}, + {0x95e8,0xe5}, + {0x95e9,0x20}, + {0x95ea,0x54}, + {0x95eb,0x07}, + {0x95ec,0xff}, + {0x95ed,0xbf}, + {0x95ee,0x01}, + {0x95ef,0x03}, + {0x95f0,0x02}, + {0x95f1,0x10}, + {0x95f2,0x7e}, + {0x95f3,0xe5}, + {0x95f4,0x20}, + {0x95f5,0x54}, + {0x95f6,0x07}, + {0x95f7,0xff}, + {0x95f8,0xbf}, + {0x95f9,0x07}, + {0x95fa,0x03}, + {0x95fb,0x02}, + {0x95fc,0x11}, + {0x95fd,0x7c}, + {0x95fe,0xe5}, + {0x95ff,0x20}, + {0x9600,0x54}, + {0x9601,0x07}, + {0x9602,0xff}, + {0x9603,0xbf}, + {0x9604,0x03}, + {0x9605,0x03}, + {0x9606,0x02}, + {0x9607,0x13}, + {0x9608,0xcc}, + {0x9609,0xe5}, + {0x960a,0x20}, + {0x960b,0x54}, + {0x960c,0x07}, + {0x960d,0xff}, + {0x960e,0xbf}, + {0x960f,0x05}, + {0x9610,0x03}, + {0x9611,0x12}, + {0x9612,0x16}, + {0x9613,0xe2}, + {0x9614,0x22}, + {0x9615,0x12}, + {0x9616,0x15}, + {0x9617,0x5d}, + {0x9618,0x12}, + {0x9619,0x16}, + {0x961a,0xf0}, + {0x961b,0x50}, + {0x961c,0x04}, + {0x961d,0xd2}, + {0x961e,0x05}, + {0x961f,0x80}, + {0x9620,0x02}, + {0x9621,0xc2}, + {0x9622,0x05}, + {0x9623,0x12}, + {0x9624,0x02}, + {0x9625,0x40}, + {0x9626,0xc2}, + {0x9627,0x39}, + {0x9628,0xc2}, + {0x9629,0x36}, + {0x962a,0xc2}, + {0x962b,0x31}, + {0x962c,0xd2}, + {0x962d,0x34}, + {0x962e,0x12}, + {0x962f,0x02}, + {0x9630,0x85}, + {0x9631,0xb5}, + {0x9632,0x07}, + {0x9633,0x03}, + {0x9634,0xd3}, + {0x9635,0x80}, + {0x9636,0x01}, + {0x9637,0xc3}, + {0x9638,0x40}, + {0x9639,0x02}, + {0x963a,0xc2}, + {0x963b,0x05}, + {0x963c,0x22}, + {0x963d,0xe4}, + {0x963e,0xff}, + {0x963f,0xfe}, + {0x9640,0xc3}, + {0x9641,0xef}, + {0x9642,0x95}, + {0x9643,0x11}, + {0x9644,0xee}, + {0x9645,0x95}, + {0x9646,0x10}, + {0x9647,0x50}, + {0x9648,0x15}, + {0x9649,0x7d}, + {0x964a,0x8a}, + {0x964b,0x7c}, + {0x964c,0x02}, + {0x964d,0xed}, + {0x964e,0x1d}, + {0x964f,0xaa}, + {0x9650,0x04}, + {0x9651,0x70}, + {0x9652,0x01}, + {0x9653,0x1c}, + {0x9654,0x4a}, + {0x9655,0x70}, + {0x9656,0xf6}, + {0x9657,0x0f}, + {0x9658,0xbf}, + {0x9659,0x00}, + {0x965a,0x01}, + {0x965b,0x0e}, + {0x965c,0x80}, + {0x965d,0xe2}, + {0x965e,0x22}, + {0x965f,0xc2}, + {0x9660,0x03}, + {0x9661,0xd2}, + {0x9662,0x04}, + {0x9663,0x12}, + {0x9664,0x02}, + {0x9665,0xa5}, + {0x9666,0x30}, + {0x9667,0x07}, + {0x9668,0x05}, + {0x9669,0x30}, + {0x966a,0x06}, + {0x966b,0x02}, + {0x966c,0xd2}, + {0x966d,0x36}, + {0x966e,0xc2}, + {0x966f,0x3e}, + {0x9670,0x12}, + {0x9671,0x0f}, + {0x9672,0xf1}, + {0x9673,0xc2}, + {0x9674,0x3e}, + {0x9675,0x12}, + {0x9676,0x12}, + {0x9677,0xad}, + {0x9678,0xd2}, + {0x9679,0x34}, + {0x967a,0x22}, + {0x967b,0x75}, + {0x967c,0x48}, + {0x967d,0x13}, + {0x967e,0x75}, + {0x967f,0x49}, + {0x9680,0x73}, + {0x9681,0x90}, + {0x9682,0x13}, + {0x9683,0x71}, + {0x9684,0xe4}, + {0x9685,0x93}, + {0x9686,0xf5}, + {0x9687,0x7b}, + {0x9688,0xa3}, + {0x9689,0xe4}, + {0x968a,0x93}, + {0x968b,0xf5}, + {0x968c,0x32}, + {0x968d,0xc2}, + {0x968e,0x3a}, + {0x968f,0x22}, + {0x9690,0xe4}, + {0x9691,0xff}, + {0x9692,0xef}, + {0x9693,0x25}, + {0x9694,0xe0}, + {0x9695,0x24}, + {0x9696,0x56}, + {0x9697,0xf8}, + {0x9698,0xe4}, + {0x9699,0xf6}, + {0x969a,0x08}, + {0x969b,0xf6}, + {0x969c,0x0f}, + {0x969d,0xbf}, + {0x969e,0x07}, + {0x969f,0xf2}, + {0x96a0,0x53}, + {0x96a1,0x24}, + {0x96a2,0x80}, + {0x96a3,0x22}, + {0x96a4,0xe5}, + {0x96a5,0x7c}, + {0x96a6,0xc3}, + {0x96a7,0x95}, + {0x96a8,0x7b}, + {0x96a9,0x40}, + {0x96aa,0x01}, + {0x96ab,0x22}, + {0x96ac,0xe5}, + {0x96ad,0x7c}, + {0x96ae,0x04}, + {0x96af,0xf5}, + {0x96b0,0x0c}, + {0x96b1,0x12}, + {0x96b2,0x0f}, + {0x96b3,0x52}, + {0x96b4,0x22}, + {0x96b5,0xe5}, + {0x96b6,0x7c}, + {0x96b7,0x70}, + {0x96b8,0x02}, + {0x96b9,0xc3}, + {0x96ba,0x22}, + {0x96bb,0xe5}, + {0x96bc,0x7c}, + {0x96bd,0x14}, + {0x96be,0xf5}, + {0x96bf,0x0c}, + {0x96c0,0x12}, + {0x96c1,0x0f}, + {0x96c2,0x52}, + {0x96c3,0x22}, + {0x96c4,0xe5}, + {0x96c5,0x7d}, + {0x96c6,0xb4}, + {0x96c7,0x01}, + {0x96c8,0x09}, + {0x96c9,0x12}, + {0x96ca,0x16}, + {0x96cb,0x7b}, + {0x96cc,0xe4}, + {0x96cd,0xf5}, + {0x96ce,0x0c}, + {0x96cf,0x12}, + {0x96d0,0x0f}, + {0x96d1,0x52}, + {0x96d2,0x22}, + {0x96d3,0xe5}, + {0x96d4,0x7d}, + {0x96d5,0x24}, + {0x96d6,0xfe}, + {0x96d7,0x60}, + {0x96d8,0x06}, + {0x96d9,0x04}, + {0x96da,0x70}, + {0x96db,0x05}, + {0x96dc,0xd2}, + {0x96dd,0x39}, + {0x96de,0x22}, + {0x96df,0xc2}, + {0x96e0,0x39}, + {0x96e1,0x22}, + {0x96e2,0xe5}, + {0x96e3,0x31}, + {0x96e4,0xd3}, + {0x96e5,0x94}, + {0x96e6,0x00}, + {0x96e7,0x40}, + {0x96e8,0x03}, + {0x96e9,0x15}, + {0x96ea,0x31}, + {0x96eb,0x22}, + {0x96ec,0x12}, + {0x96ed,0x16}, + {0x96ee,0x5f}, + {0x96ef,0x22}, + {0x96f0,0x12}, + {0x96f1,0x16}, + {0x96f2,0x7b}, + {0x96f3,0xe4}, + {0x96f4,0xf5}, + {0x96f5,0x0c}, + {0x96f6,0x12}, + {0x96f7,0x0f}, + {0x96f8,0x52}, + {0x96f9,0x22}, + {0x3024,0x00}, + {0x3025,0x00}, + {0x5082,0x00}, + {0x5083,0x00}, + {0x5084,0x00}, + {0x5085,0x00}, + {0x3026,0x00}, + {0x3027,0xFF}, + {0x3000,0x00}, + {0x0000,0x00} +} #endif diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 50b415e07eda..f7f7e04cf485 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -753,7 +753,7 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) buf[0] = 0xff; /* fixed */ ret = send_control_msg(pdev, - SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf)); + SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, 1); if (!mode && ret >= 0) { if (value < 0) diff --git a/drivers/media/video/rk29_camera_oneframe.c b/drivers/media/video/rk29_camera_oneframe.c index 4593b8e5ffe4..6e1f75785647 100644 --- a/drivers/media/video/rk29_camera_oneframe.c +++ b/drivers/media/video/rk29_camera_oneframe.c @@ -39,6 +39,8 @@ #include #include +#include + // VIP Reg Offset #define RK29_VIP_AHBR_CTRL 0x00 #define RK29_VIP_INT_MASK 0x04 @@ -188,6 +190,12 @@ struct rk29_camera_reg unsigned int VipCrm; enum rk29_camera_reg_state Inval; }; +struct rk29_camera_work +{ + struct videobuf_buffer *vb; + struct rk29_camera_dev *pcdev; + struct work_struct work; +}; struct rk29_camera_dev { struct soc_camera_host soc_host; @@ -201,6 +209,12 @@ struct rk29_camera_dev void __iomem *grf_base; int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */ unsigned int irq; + unsigned int pixfmt; + unsigned int vipmem_phybase; + unsigned int vipmem_size; + unsigned int vipmem_bsize; + int host_width; + int host_height; struct rk29camera_platform_data *pdata; struct resource *res; @@ -212,6 +226,8 @@ struct rk29_camera_dev struct videobuf_buffer *active; struct videobuf_queue *vb_vidq_ptr; struct rk29_camera_reg reginfo_suspend; + struct workqueue_struct *camera_wq; + struct rk29_camera_work *camera_work; }; static DEFINE_MUTEX(camera_lock); static const char *rk29_cam_driver_description = "RK29_Camera"; @@ -227,14 +243,26 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) { struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk29_camera_dev *pcdev = ici->priv; int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); - /* planar capture requires Y, U and V buffers to be page aligned */ - *size = PAGE_ALIGN( icd->user_width * icd->user_height * bytes_per_pixel); /* Y pages UV pages, yuv422*/ + if (pcdev->camera_work == NULL) { + pcdev->camera_work = kmalloc(sizeof(struct rk29_camera_work)*(*count), GFP_KERNEL); + if (pcdev->camera_work == NULL) + RK29CAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__); + } - RK29CAMERA_DG("\n%s..%d.. size = %d\n",__FUNCTION__,__LINE__, *size); + /* planar capture requires Y, U and V buffers to be page aligned */ + *size = PAGE_ALIGN(icd->user_width* icd->user_height * bytes_per_pixel); /* Y pages UV pages, yuv422*/ + pcdev->vipmem_bsize = PAGE_ALIGN(pcdev->host_width * pcdev->host_height * bytes_per_pixel); + + if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) + BUG_ON(pcdev->vipmem_bsize*(*count) > pcdev->vipmem_size); + + RK29CAMERA_DG("\n%s..%d.. videobuf size:%d, vipmem_buf size:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_bsize); return 0; } @@ -260,6 +288,7 @@ static void rk29_videobuf_free(struct videobuf_queue *vq, struct rk29_buffer *bu static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct rk29_buffer *buf; int ret; @@ -290,7 +319,7 @@ static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buff vb->state = VIDEOBUF_NEEDS_INIT; } - vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3) ; /* ddl@rock-chips.com : fmt->depth is coorect */ + vb->size = (((vb->width * vb->height *buf->fmt->depth) + 7) >> 3) ; /* ddl@rock-chips.com : fmt->depth is coorect */ if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; @@ -313,14 +342,21 @@ static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buff static inline void rk29_videobuf_capture(struct videobuf_buffer *vb) { - unsigned int size; + unsigned int y_addr,uv_addr; + struct rk29_camera_dev *pcdev = rk29_camdev_info_ptr; if (vb) { - size = vb->width * vb->height; /* Y pages UV pages, yuv422*/ - write_vip_reg(RK29_VIP_CAPTURE_F1SA_Y, vb->boff); - write_vip_reg(RK29_VIP_CAPTURE_F1SA_UV, vb->boff + size); - write_vip_reg(RK29_VIP_CAPTURE_F2SA_Y, vb->boff); - write_vip_reg(RK29_VIP_CAPTURE_F2SA_UV, vb->boff + size); + if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) { + y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize; + uv_addr = y_addr + pcdev->host_width*pcdev->host_height; + } else { + y_addr = vb->boff; + uv_addr = y_addr + vb->width * vb->height; + } + write_vip_reg(RK29_VIP_CAPTURE_F1SA_Y, y_addr); + write_vip_reg(RK29_VIP_CAPTURE_F1SA_UV, uv_addr); + write_vip_reg(RK29_VIP_CAPTURE_F2SA_Y, y_addr); + write_vip_reg(RK29_VIP_CAPTURE_F2SA_UV, uv_addr); write_vip_reg(RK29_VIP_FB_SR, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used } } @@ -337,7 +373,7 @@ static void rk29_videobuf_queue(struct videobuf_queue *vq, vb->state = VIDEOBUF_QUEUED; - if (!list_empty(&pcdev->capture)) { + if (list_empty(&pcdev->capture)) { list_add_tail(&vb->queue, &pcdev->capture); } else { if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb) @@ -351,10 +387,76 @@ static void rk29_videobuf_queue(struct videobuf_queue *vq, rk29_videobuf_capture(vb); } } +static int rk29_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt) +{ + switch (pixfmt) + { + case V4L2_PIX_FMT_YUV422P: + { + *ippfmt = IPP_Y_CBCR_H2V1; + break; + } + case V4L2_PIX_FMT_YUV420: + { + *ippfmt = IPP_Y_CBCR_H2V2; + break; + } + default: + goto rk29_pixfmt2ippfmt_err; + } + + return 0; +rk29_pixfmt2ippfmt_err: + return -1; +} +static void rk29_camera_capture_process(struct work_struct *work) +{ + struct rk29_camera_work *camera_work = container_of(work, struct rk29_camera_work, work); + struct videobuf_buffer *vb = camera_work->vb; + struct rk29_camera_dev *pcdev = camera_work->pcdev; + struct rk29_ipp_req ipp_req; + unsigned int flags; + + ipp_req.src0.YrgbMst = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize; + ipp_req.src0.CbrMst= ipp_req.src0.YrgbMst + pcdev->host_width*pcdev->host_height; + ipp_req.src0.w = pcdev->host_width; + ipp_req.src0.h = pcdev->host_height; + rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt); + + ipp_req.dst0.YrgbMst = vb->boff; + ipp_req.dst0.CbrMst= vb->boff+vb->width * vb->height; + ipp_req.dst0.w = pcdev->icd->user_width; + ipp_req.dst0.h = pcdev->icd->user_height; + rk29_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt); + + ipp_req.src_vir_w = ipp_req.src0.w; + ipp_req.dst_vir_w = ipp_req.dst0.w; + ipp_req.timeout = 100; + ipp_req.flag = IPP_ROT_0; + + if (ipp_do_blit(&ipp_req)) { + spin_lock_irqsave(&pcdev->lock, flags); + vb->state = VIDEOBUF_ERROR; + spin_unlock_irqrestore(&pcdev->lock, flags); + RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error!\n", vb->i); + RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst); + RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h); + RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt); + RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst); + RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h); + RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt); + RK29CAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w); + RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag); + } + + wake_up(&(camera_work->vb->done)); +} + static irqreturn_t rk29_camera_irq(int irq, void *data) { struct rk29_camera_dev *pcdev = data; struct videobuf_buffer *vb; + struct rk29_camera_work *wk; read_vip_reg(RK29_VIP_INT_STS); /* clear vip interrupte single */ @@ -397,7 +499,15 @@ static irqreturn_t rk29_camera_irq(int irq, void *data) vb->field_count++; } - wake_up(&vb->done); + if ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) { + wk = pcdev->camera_work + vb->i; + INIT_WORK(&(wk->work), rk29_camera_capture_process); + wk->vb = vb; + wk->pcdev = pcdev; + queue_work(pcdev->camera_wq, &(wk->work)); + } else { + wake_up(&vb->done); + } } RK29_CAMERA_IRQ_END: @@ -596,6 +706,11 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd) pcdev->vb_vidq_ptr = NULL; } + if (pcdev->camera_work) { + kfree(pcdev->camera_work); + pcdev->camera_work = NULL; + } + pcdev->active = NULL; pcdev->icd = NULL; pcdev->reginfo_suspend.Inval = Reg_Invalidate; @@ -717,15 +832,18 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p case V4L2_PIX_FMT_YUV422P: vip_ctrl_val |= VIPREGYUV422; pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC; + pcdev->pixfmt = host_pixfmt; break; case V4L2_PIX_FMT_YUV420: vip_ctrl_val |= VIPREGYUV420; if (pcdev->frame_inval != RK29_CAM_FRAME_INVAL_INIT) pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT; + pcdev->pixfmt = host_pixfmt; break; case V4L2_PIX_FMT_SGRBG10: vip_ctrl_val |= (VIP_RAW | VIP_SENSOR | VIP_DATA_LITTLEEND); pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC; + pcdev->pixfmt = host_pixfmt; break; default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */ vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & VIPREGYUV422); @@ -753,12 +871,7 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p vip_crop = ((rect->left<<16) + rect->top); vip_fs = (((rect->width + rect->left)<<16) + (rect->height+rect->top)); } else if (vip_ctrl_val & PING_PONG) { - if (rect->left ||rect->top ) { - RK29CAMERA_DG("\n %s..PingPang not support Crop \n",__FUNCTION__); - BUG(); - } - vip_crop = 0; - vip_fs = (((rect->width + rect->left)<<16) + (rect->height+rect->top)); + BUG(); } write_vip_reg(RK29_VIP_CROP, vip_crop); @@ -766,6 +879,9 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p write_vip_reg(RK29_VIP_FB_SR, 0x00000003); + pcdev->host_width = rect->width; + pcdev->host_height = rect->height; + RK29CAMERA_DG("\n%s.. crop:0x%x fs:0x%x ctrl:0x%x CtrlReg:0x%x\n",__FUNCTION__,vip_crop,vip_fs,vip_ctrl_val,read_vip_reg(RK29_VIP_CTRL)); return; } @@ -874,12 +990,16 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_data_format *cam_fmt = NULL; const struct soc_camera_format_xlate *xlate = NULL; + struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent); + struct rk29_camera_dev *pcdev = ici->priv; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_format cam_f = *f; struct v4l2_rect rect; - int ret; + int ret,usr_w,usr_h; - RK29CAMERA_DG("\n%s..%d.. \n",__FUNCTION__,__LINE__); + usr_w = pix->width; + usr_h = pix->height; + RK29CAMERA_DG("\n%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h); xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); if (!xlate) { @@ -894,20 +1014,29 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd, ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f); cam_f.fmt.pix.pixelformat = pix->pixelformat; *pix = cam_f.fmt.pix; - + #ifdef CONFIG_VIDEO_RK29_WORK_IPP + if ((pix->width != usr_w) || (pix->height != usr_h)) { + pix->width = usr_w; + pix->height = usr_h; + } + #endif icd->sense = NULL; if (!ret) { rect.left = 0; rect.top = 0; - rect.width = pix->width; - rect.height = pix->height; + rect.width = cam_f.fmt.pix.width; + rect.height = cam_f.fmt.pix.height; - RK29CAMERA_DG("\n%s..%s..%s \n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name); + RK29CAMERA_DG("\n%s..%s..%s icd width:%d host width:%d \n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name, + rect.width, pix->width); rk29_camera_setup_format(icd, pix->pixelformat, cam_fmt->fourcc, &rect); - icd->buswidth = xlate->buswidth; icd->current_fmt = xlate->host_fmt; + + if (((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))) { + BUG_ON(pcdev->vipmem_phybase == 0); + } } RK29_CAMERA_SET_FMT_END: @@ -925,9 +1054,11 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_pix_format *pix = &f->fmt.pix; __u32 pixfmt = pix->pixelformat; enum v4l2_field field; - int ret; + int ret,usr_w,usr_h; - RK29CAMERA_DG("\n%s..%d.. \n",__FUNCTION__,__LINE__); + usr_w = pix->width; + usr_h = pix->height; + RK29CAMERA_DG("\n%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h); xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { @@ -948,6 +1079,17 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd, /* limit to sensor capabilities */ ret = v4l2_subdev_call(sd, video, try_fmt, f); pix->pixelformat = pixfmt; + #ifdef CONFIG_VIDEO_RK29_WORK_IPP + if ((pix->width > usr_w) && (pix->height > usr_h)) { + pix->width = usr_w; + pix->height = usr_h; + } else if ((pix->width < usr_w) && (pix->height < usr_h)) { + if (((usr_w>>1) < pix->width) && ((usr_h>>1) < pix->height)) { + pix->width = usr_w; + pix->height = usr_h; + } + } + #endif field = pix->field; @@ -1150,7 +1292,17 @@ static int rk29_camera_probe(struct platform_device *pdev) if (pcdev->pdata && pcdev->pdata->io_init) { pcdev->pdata->io_init(); } - + #ifdef CONFIG_VIDEO_RK29_WORK_IPP + if (pcdev->pdata && (strcmp(pcdev->pdata->meminfo.name,"camera_ipp_mem")==0)) { + pcdev->vipmem_phybase = pcdev->pdata->meminfo.start; + pcdev->vipmem_size = pcdev->pdata->meminfo.size; + RK29CAMERA_TR("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size); + } else { + RK29CAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__); + pcdev->vipmem_phybase = 0; + pcdev->vipmem_size = 0; + } + #endif INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); @@ -1182,6 +1334,10 @@ static int rk29_camera_probe(struct platform_device *pdev) goto exit_reqirq; } + pcdev->camera_wq = create_workqueue("camera wq"); + if (pcdev->camera_wq == NULL) + goto exit_free_irq; + pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME; pcdev->soc_host.ops = &rk29_soc_camera_host_ops; pcdev->soc_host.priv = pcdev; diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index f87757fccc72..09d42236f748 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -420,19 +420,6 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) ctrl |= SAA7134_MAIN_CTRL_TE5; irq |= SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0; - - /* dma: setup channel 5 (= TS) */ - - saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); - saa_writeb(SAA7134_TS_DMA1, - ((dev->ts.nr_packets - 1) >> 8) & 0xff); - /* TSNOPIT=0, TSCOLAP=0 */ - saa_writeb(SAA7134_TS_DMA2, - (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); - saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); - saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | - SAA7134_RS_CONTROL_ME | - (dev->ts.pt_ts.dma >> 12)); } /* set task conditions + field handling */ diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index 03488ba4c99c..b9817d74943f 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c @@ -250,6 +250,19 @@ int saa7134_ts_start(struct saa7134_dev *dev) BUG_ON(dev->ts_started); + /* dma: setup channel 5 (= TS) */ + saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); + saa_writeb(SAA7134_TS_DMA1, + ((dev->ts.nr_packets - 1) >> 8) & 0xff); + /* TSNOPIT=0, TSCOLAP=0 */ + saa_writeb(SAA7134_TS_DMA2, + (((dev->ts.nr_packets - 1) >> 16) & 0x3f) | 0x00); + saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); + saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | + SAA7134_RS_CONTROL_ME | + (dev->ts.pt_ts.dma >> 12)); + + /* reset hardware TS buffers */ saa_writeb(SAA7134_TS_SERIAL1, 0x00); saa_writeb(SAA7134_TS_SERIAL1, 0x03); saa_writeb(SAA7134_TS_SERIAL1, 0x00); diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 4a293b444459..0ca39ec4ba8e 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -826,6 +826,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, ret = 0; goto out; + case V4L2_CTRL_TYPE_BUTTON: + v4l2_ctrl->minimum = 0; + v4l2_ctrl->maximum = 0; + v4l2_ctrl->step = 0; + ret = 0; + goto out; + default: break; } diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 8756be569154..eb2ce2630a77 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -57,6 +57,11 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_YUY2, .fcc = V4L2_PIX_FMT_YUYV, }, + { + .name = "YUV 4:2:2 (YUYV)", + .guid = UVC_GUID_FORMAT_YUY2_ISIGHT, + .fcc = V4L2_PIX_FMT_YUYV, + }, { .name = "YUV 4:2:0 (NV12)", .guid = UVC_GUID_FORMAT_NV12, @@ -83,10 +88,15 @@ static struct uvc_format_desc uvc_fmts[] = { .fcc = V4L2_PIX_FMT_UYVY, }, { - .name = "Greyscale", + .name = "Greyscale (8-bit)", .guid = UVC_GUID_FORMAT_Y800, .fcc = V4L2_PIX_FMT_GREY, }, + { + .name = "Greyscale (16-bit)", + .guid = UVC_GUID_FORMAT_Y16, + .fcc = V4L2_PIX_FMT_Y16, + }, { .name = "RGB Bayer", .guid = UVC_GUID_FORMAT_BY8, @@ -426,7 +436,8 @@ static int uvc_parse_format(struct uvc_device *dev, /* Parse the frame descriptors. Only uncompressed, MJPEG and frame * based formats have frame descriptors. */ - while (buflen > 2 && buffer[2] == ftype) { + while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + buffer[2] == ftype) { frame = &format->frame[format->nframes]; if (ftype != UVC_VS_FRAME_FRAME_BASED) n = buflen > 25 ? buffer[25] : 0; @@ -503,12 +514,14 @@ static int uvc_parse_format(struct uvc_device *dev, buffer += buffer[0]; } - if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { + if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { buflen -= buffer[0]; buffer += buffer[0]; } - if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) { + if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + buffer[2] == UVC_VS_COLORFORMAT) { if (buflen < 6) { uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d COLORFORMAT error\n", @@ -749,6 +762,11 @@ static int uvc_parse_streaming(struct uvc_device *dev, buffer += buffer[0]; } + if (buflen) + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " + "%d has %u bytes of trailing descriptor garbage.\n", + dev->udev->devnum, alts->desc.bInterfaceNumber, buflen); + /* Parse the alternate settings to find the maximum bandwidth. */ for (i = 0; i < intf->num_altsetting; ++i) { struct usb_host_endpoint *ep; @@ -2048,6 +2066,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, + /* Syntek (Packard Bell EasyNote MX52 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x174f, + .idProduct = 0x8a12, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* Syntek (Asus F9SG) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2112,6 +2139,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* Arkmicro unbranded */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x18ec, + .idProduct = 0x3290, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_DEF }, /* Bodelin ProScopeHR */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_HI diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index e7958aa454ce..64007b90bd73 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -112,6 +112,9 @@ struct uvc_xu_control { #define UVC_GUID_FORMAT_YUY2 \ { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_YUY2_ISIGHT \ + { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_NV12 \ { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} @@ -127,11 +130,13 @@ struct uvc_xu_control { #define UVC_GUID_FORMAT_Y800 \ { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_Y16 \ + { 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} #define UVC_GUID_FORMAT_BY8 \ { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} - /* ------------------------------------------------------------------------ * Driver specific constants. */ diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index 997975d5e024..64076ffec0e0 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c @@ -193,17 +193,24 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u struct video_code32 { char loadwhat[16]; /* name or tag of file being passed */ compat_int_t datasize; - unsigned char *data; + compat_uptr_t data; }; -static int get_microcode32(struct video_code *kp, struct video_code32 __user *up) +static struct video_code __user *get_microcode32(struct video_code32 *kp) { - if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) || - copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) || - get_user(kp->datasize, &up->datasize) || - copy_from_user(kp->data, up->data, up->datasize)) - return -EFAULT; - return 0; + struct video_code __user *up; + + up = compat_alloc_user_space(sizeof(*up)); + + /* + * NOTE! We don't actually care if these fail. If the + * user address is invalid, the native ioctl will do + * the error handling for us + */ + (void) copy_to_user(up->loadwhat, kp->loadwhat, sizeof(up->loadwhat)); + (void) put_user(kp->datasize, &up->datasize); + (void) put_user(compat_ptr(kp->data), &up->data); + return up; } #define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32) @@ -741,7 +748,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar struct video_tuner vt; struct video_buffer vb; struct video_window vw; - struct video_code vc; + struct video_code32 vc; struct video_audio va; #endif struct v4l2_format v2f; @@ -820,8 +827,11 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar break; case VIDIOCSMICROCODE: - err = get_microcode32(&karg.vc, up); - compatible_arg = 0; + /* Copy the 32-bit "video_code32" to kernel space */ + if (copy_from_user(&karg.vc, up, sizeof(karg.vc))) + return -EFAULT; + /* Convert the 32-bit version to a 64-bit version in user space */ + up = get_microcode32(&karg.vc); break; case VIDIOCSFREQ: diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index bd83fa0a4970..46bd7e2a952c 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -1330,13 +1330,14 @@ static void mspro_block_remove(struct memstick_dev *card) struct mspro_block_data *msb = memstick_get_drvdata(card); unsigned long flags; - del_gendisk(msb->disk); - dev_dbg(&card->dev, "mspro block remove\n"); spin_lock_irqsave(&msb->q_lock, flags); msb->eject = 1; blk_start_queue(msb->queue); spin_unlock_irqrestore(&msb->q_lock, flags); + del_gendisk(msb->disk); + dev_dbg(&card->dev, "mspro block remove\n"); + blk_cleanup_queue(msb->queue); msb->queue = NULL; diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 9b2e2198aee9..352acd05c46b 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -621,11 +621,8 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) */ iocnumX = khdr.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || - (iocp == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnumX); + (iocp == NULL)) return -ENODEV; - } if (!iocp->active) { printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n", diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 6cea7181ed73..56d98eb20a25 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -792,11 +792,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) * precedence! */ sc->result = (DID_OK << 16) | scsi_status; - if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { - /* Have already saved the status and sense data + if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) { + + /* + * For an Errata on LSI53C1030 + * When the length of request data + * and transfer data are different + * with result of command (READ or VERIFY), + * DID_SOFT_ERROR is set. */ - ; - } else { + if (ioc->bus_type == SPI) { + if (pScsiReq->CDB[0] == READ_6 || + pScsiReq->CDB[0] == READ_10 || + pScsiReq->CDB[0] == READ_12 || + pScsiReq->CDB[0] == READ_16 || + pScsiReq->CDB[0] == VERIFY || + pScsiReq->CDB[0] == VERIFY_16) { + if (scsi_bufflen(sc) != + xfer_cnt) { + sc->result = + DID_SOFT_ERROR << 16; + printk(KERN_WARNING "Errata" + "on LSI53C1030 occurred." + "sc->req_bufflen=0x%02x," + "xfer_cnt=0x%02x\n", + scsi_bufflen(sc), + xfer_cnt); + } + } + } + if (xfer_cnt < sc->underflow) { if (scsi_status == SAM_STAT_BUSY) sc->result = SAM_STAT_BUSY; @@ -835,7 +860,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) sc->result = (DID_OK << 16) | scsi_status; if (scsi_state == 0) { ; - } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { + } else if (scsi_state & + MPI_SCSI_STATE_AUTOSENSE_VALID) { + + /* + * For potential trouble on LSI53C1030. + * (date:2007.xx.) + * It is checked whether the length of + * request data is equal to + * the length of transfer and residual. + * MEDIUM_ERROR is set by incorrect data. + */ + if ((ioc->bus_type == SPI) && + (sc->sense_buffer[2] & 0x20)) { + u32 difftransfer; + difftransfer = + sc->sense_buffer[3] << 24 | + sc->sense_buffer[4] << 16 | + sc->sense_buffer[5] << 8 | + sc->sense_buffer[6]; + if (((sc->sense_buffer[3] & 0x80) == + 0x80) && (scsi_bufflen(sc) + != xfer_cnt)) { + sc->sense_buffer[2] = + MEDIUM_ERROR; + sc->sense_buffer[12] = 0xff; + sc->sense_buffer[13] = 0xff; + printk(KERN_WARNING"Errata" + "on LSI53C1030 occurred." + "sc->req_bufflen=0x%02x," + "xfer_cnt=0x%02x\n" , + scsi_bufflen(sc), + xfer_cnt); + } + if (((sc->sense_buffer[3] & 0x80) + != 0x80) && + (scsi_bufflen(sc) != + xfer_cnt + difftransfer)) { + sc->sense_buffer[2] = + MEDIUM_ERROR; + sc->sense_buffer[12] = 0xff; + sc->sense_buffer[13] = 0xff; + printk(KERN_WARNING + "Errata on LSI53C1030 occurred" + "sc->req_bufflen=0x%02x," + " xfer_cnt=0x%02x," + "difftransfer=0x%02x\n", + scsi_bufflen(sc), + xfer_cnt, + difftransfer); + } + } + /* * If running against circa 200003dd 909 MPT f/w, * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL @@ -2363,6 +2439,8 @@ mptscsih_slave_configure(struct scsi_device *sdev) ioc->name,sdev->tagged_supported, sdev->simple_tags, sdev->ordered_tags)); + blk_queue_dma_alignment (sdev->request_queue, 512 - 1); + return 0; } diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 1eac626e710a..68e4cd7d321a 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -284,8 +284,11 @@ enclosure_component_register(struct enclosure_device *edev, cdev->groups = enclosure_groups; err = device_register(cdev); - if (err) - ERR_PTR(err); + if (err) { + ecomp->number = -1; + put_device(cdev); + return ERR_PTR(err); + } return ecomp; } diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index 65877bc5edaa..55748d6a6265 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c @@ -433,18 +433,23 @@ xpc_discovery(void) * nodes that can comprise an access protection grouping. The access * protection is in regards to memory, IOI and IPI. */ - max_regions = 64; region_size = xp_region_size; - switch (region_size) { - case 128: - max_regions *= 2; - case 64: - max_regions *= 2; - case 32: - max_regions *= 2; - region_size = 16; - DBUG_ON(!is_shub2()); + if (is_uv()) + max_regions = 256; + else { + max_regions = 64; + + switch (region_size) { + case 128: + max_regions *= 2; + case 64: + max_regions *= 2; + case 32: + max_regions *= 2; + region_size = 16; + DBUG_ON(!is_shub2()); + } } for (region = 0; region < max_regions; region++) { diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index c76677afda1b..8e08d71df104 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -203,6 +203,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, enum xp_retval xp_ret; int ret; int nid; + int nasid; int pg_order; struct page *page; struct xpc_gru_mq_uv *mq; @@ -258,9 +259,11 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, goto out_5; } + nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu)); + mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value; ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size, - nid, mmr_value->vector, mmr_value->dest); + nasid, mmr_value->vector, mmr_value->dest); if (ret != 0) { dev_err(xpc_part, "gru_create_message_queue() returned " "error=%d\n", ret); @@ -409,6 +412,7 @@ xpc_process_activate_IRQ_rcvd_uv(void) static void xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, struct xpc_activate_mq_msghdr_uv *msg_hdr, + int part_setup, int *wakeup_hb_checker) { unsigned long irq_flags; @@ -473,6 +477,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; + if (!part_setup) + break; + msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_closerequest_uv, hdr); @@ -489,6 +496,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { struct xpc_activate_mq_msg_chctl_closereply_uv *msg; + if (!part_setup) + break; + msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_closereply_uv, hdr); @@ -503,6 +513,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; + if (!part_setup) + break; + msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_openrequest_uv, hdr); @@ -520,6 +533,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { struct xpc_activate_mq_msg_chctl_openreply_uv *msg; + if (!part_setup) + break; + msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_openreply_uv, hdr); args = &part->remote_openclose_args[msg->ch_number]; @@ -537,6 +553,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; + if (!part_setup) + break; + msg = container_of(msg_hdr, struct xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); spin_lock_irqsave(&part->chctl_lock, irq_flags); @@ -613,6 +632,7 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id) part_referenced = xpc_part_ref(part); xpc_handle_activate_mq_msg_uv(part, msg_hdr, + part_referenced, &wakeup_hb_checker); if (part_referenced) xpc_part_deref(part); @@ -945,11 +965,13 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head) head->first = first->next; if (head->first == NULL) head->last = NULL; + + head->n_entries--; + BUG_ON(head->n_entries < 0); + + first->next = NULL; } - head->n_entries--; - BUG_ON(head->n_entries < 0); spin_unlock_irqrestore(&head->lock, irq_flags); - first->next = NULL; return first; } @@ -1018,7 +1040,8 @@ xpc_make_first_contact_uv(struct xpc_partition *part) xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV); - while (part->sn.uv.remote_act_state != XPC_P_AS_ACTIVATING) { + while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) || + (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) { dev_dbg(xpc_part, "waiting to make first contact with " "partition %d\n", XPC_PARTID(part)); @@ -1421,7 +1444,6 @@ xpc_handle_notify_mq_msg_uv(struct xpc_partition *part, 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); memcpy(msg_slot, msg, msg->hdr.size); @@ -1645,8 +1667,6 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload) sizeof(struct xpc_notify_mq_msghdr_uv)); if (ret != xpSuccess) XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); - - msg->hdr.msg_slot_number += ch->remote_nentries; } static struct xpc_arch_operations xpc_arch_ops_uv = { diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index fc25586b7ee1..8faa703516b5 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -530,9 +530,10 @@ static void atmci_dma_cleanup(struct atmel_mci *host) { struct mmc_data *data = host->data; - dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, - ((data->flags & MMC_DATA_WRITE) - ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); + if (data) + dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, + ((data->flags & MMC_DATA_WRITE) + ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); } static void atmci_stop_dma(struct atmel_mci *host) @@ -1037,8 +1038,8 @@ static void atmci_command_complete(struct atmel_mci *host, "command error: status=0x%08x\n", status); if (cmd->data) { - host->data = NULL; atmci_stop_dma(host); + host->data = NULL; mci_writel(host, IDR, MCI_NOTBUSY | MCI_TXRDY | MCI_RXRDY | ATMCI_DATA_ERROR_FLAGS); @@ -1229,6 +1230,7 @@ static void atmci_tasklet_func(unsigned long priv) } else { data->bytes_xfered = data->blocks * data->blksz; data->error = 0; + mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS); } if (!data->stop) { @@ -1669,13 +1671,13 @@ static int __init atmci_probe(struct platform_device *pdev) ret = -ENODEV; if (pdata->slot[0].bus_width) { ret = atmci_init_slot(host, &pdata->slot[0], - MCI_SDCSEL_SLOT_A, 0); + 0, MCI_SDCSEL_SLOT_A); if (!ret) nr_slots++; } if (pdata->slot[1].bus_width) { ret = atmci_init_slot(host, &pdata->slot[1], - MCI_SDCSEL_SLOT_B, 1); + 1, MCI_SDCSEL_SLOT_B); if (!ret) nr_slots++; } diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 99b74a351020..fba147c3f54c 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1178,7 +1178,7 @@ static int s3cmci_card_present(struct mmc_host *mmc) struct s3c24xx_mci_pdata *pdata = host->pdata; int ret; - if (pdata->gpio_detect == 0) + if (pdata->no_detect) return -ENOSYS; ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; @@ -1361,6 +1361,8 @@ static struct mmc_host_ops s3cmci_ops = { static struct s3c24xx_mci_pdata s3cmci_def_pdata = { /* This is currently here to avoid a number of if (host->pdata) * checks. Any zero fields to ensure reaonable defaults are picked. */ + .no_wprotect = 1, + .no_detect = 1, }; #ifdef CONFIG_CPU_FREQ diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 50997d2a63e7..14c5480e059c 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -372,6 +372,28 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) static int __devexit sdhci_s3c_remove(struct platform_device *pdev) { + struct sdhci_host *host = platform_get_drvdata(pdev); + struct sdhci_s3c *sc = sdhci_priv(host); + int ptr; + + sdhci_remove_host(host, 1); + + for (ptr = 0; ptr < 3; ptr++) { + if (sc->clk_bus[ptr]) { + clk_disable(sc->clk_bus[ptr]); + clk_put(sc->clk_bus[ptr]); + } + } + clk_disable(sc->clk_io); + clk_put(sc->clk_io); + + iounmap(host->ioaddr); + release_resource(sc->ioarea); + kfree(sc->ioarea); + + sdhci_free_host(host); + platform_set_drvdata(pdev, NULL); + return 0; } diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 91991b460c45..f43edfd064c1 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -161,6 +161,7 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) { struct mmc_data *data = host->data; + void *sg_virt; unsigned short *buf; unsigned int count; unsigned long flags; @@ -170,8 +171,8 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) return; } - buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) + - host->sg_off); + sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, &flags); + buf = (unsigned short *)(sg_virt + host->sg_off); count = host->sg_ptr->length - host->sg_off; if (count > data->blksz) @@ -188,7 +189,7 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) host->sg_off += count; - tmio_mmc_kunmap_atomic(host, &flags); + tmio_mmc_kunmap_atomic(sg_virt, &flags); if (host->sg_off == host->sg_ptr->length) tmio_mmc_next_sg(host); diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9fa998594974..ee8fa89b2b57 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -102,10 +102,7 @@ #define ack_mmc_irqs(host, i) \ do { \ - u32 mask;\ - mask = sd_ctrl_read32((host), CTL_STATUS); \ - mask &= ~((i) & TMIO_MASK_IRQ); \ - sd_ctrl_write32((host), CTL_STATUS, mask); \ + sd_ctrl_write32((host), CTL_STATUS, ~(i)); \ } while (0) @@ -200,19 +197,17 @@ static inline int tmio_mmc_next_sg(struct tmio_mmc_host *host) return --host->sg_len; } -static inline char *tmio_mmc_kmap_atomic(struct tmio_mmc_host *host, +static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg, unsigned long *flags) { - struct scatterlist *sg = host->sg_ptr; - local_irq_save(*flags); return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; } -static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host, +static inline void tmio_mmc_kunmap_atomic(void *virt, unsigned long *flags) { - kunmap_atomic(sg_page(host->sg_ptr), KM_BIO_SRC_IRQ); + kunmap_atomic(virt, KM_BIO_SRC_IRQ); local_irq_restore(*flags); } diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 6ea520ae2410..776183fb2b59 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -316,7 +316,7 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = { #define tAR_NDTR1(r) (((r) >> 0) & 0xf) /* convert nano-seconds to nand flash controller clock cycles */ -#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1) +#define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) /* convert nand flash controller clock cycles to nano-seconds */ #define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000)) diff --git a/drivers/mtd/nand/rk29_nand.c b/drivers/mtd/nand/rk29_nand.c index 6d2beeee00e8..222d2d8ef8cb 100644 --- a/drivers/mtd/nand/rk29_nand.c +++ b/drivers/mtd/nand/rk29_nand.c @@ -137,7 +137,7 @@ static void rk29_nand_wait_bchdone(struct mtd_info *mtd, uint32_t timeout) { timeout--; udelay(1); - if(pRK29NC->BCHST &(1<<1)) + if(pRK29NC->BCHST[0] &(1<<1)) break; } @@ -324,15 +324,13 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_READID: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); pRK29NC ->chip[master->cs].addr = 0x0; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,READ_BUSY_COUNT); break; case NAND_CMD_READ0: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( column>= 0 ) { pRK29NC ->chip[master->cs].addr = column & 0xff; @@ -345,11 +343,10 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, pRK29NC ->chip[master->cs].addr = (page_addr >> 8) & 0xFF; pRK29NC ->chip[master->cs].addr = (page_addr >> 16) & 0xff; } - rk29_nand_wait_ready(mtd); if( mtd->writesize > 512) - pRK29NC ->chip[0].cmd = NAND_CMD_READSTART; + pRK29NC ->chip[master->cs].cmd = NAND_CMD_READSTART; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,READ_BUSY_COUNT); break; @@ -366,7 +363,6 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( mtd->writesize >512 ) { if ( column>= 0 ) @@ -386,8 +382,7 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, { pRK29NC ->chip[master->cs].addr = column; } - rk29_nand_wait_ready(mtd); - + udelay(1); rk29_nand_wait_busy(mtd,READ_BUSY_COUNT); @@ -396,11 +391,10 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_PAGEPROG: pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,PROGRAM_BUSY_COUNT); pRK29NC ->chip[master->cs].cmd = NAND_CMD_STATUS; - rk29_nand_wait_ready(mtd); status = pRK29NC ->chip[master->cs].data; if(status&0x1) @@ -414,7 +408,6 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->BCHCTL = 0x0; pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( page_addr>=0 ) { pRK29NC ->chip[master->cs].addr = page_addr & 0xff; @@ -426,10 +419,8 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_ERASE2: pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); rk29_nand_wait_busy(mtd,ERASE_BUSY_COUNT); pRK29NC ->chip[master->cs].cmd = NAND_CMD_STATUS; - rk29_nand_wait_ready(mtd); status = pRK29NC ->chip[master->cs].data; if(status&0x1) @@ -442,7 +433,6 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_SEQIN: pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( column>= 0 ) { pRK29NC ->chip[master->cs].addr = column; @@ -461,19 +451,17 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_STATUS: pRK29NC ->BCHCTL = 0x0; pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); break; case NAND_CMD_RESET: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,RESET_BUSY_COUNT); break; /* This applies to read commands */ default: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); break; } @@ -521,7 +509,7 @@ int rk29_nand_calculate_ecc(struct mtd_info *mtd,const uint8_t *dat,uint8_t *ecc pNANDC pRK29NC= (pNANDC)(master->regs); // hw correct data - if( pRK29NC->BCHST & (1<<2) ) + if( pRK29NC->BCHST[0] & (1<<2) ) { DEBUG(MTD_DEBUG_LEVEL0, "rk2818 nand :hw ecc uncorrectable error\n"); @@ -561,7 +549,7 @@ int rk29_nand_calculate_ecc(struct mtd_info *mtd,const uint8_t *dat,uint8_t *ecc pRK29NC ->BCHCTL = BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ; wait_op_done(mtd,TROP_US_DELAY,0); - //rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; + rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; memcpy(buf+i*0x400,(u_char *)(pRK29NC->buf),0x400); // only use nandc sram0 } @@ -597,16 +585,16 @@ void rk29_nand_write_page(struct mtd_info *mtd,struct nand_chip *chip,const uin for(i=0;iwritesize/0x400;i++) { + pRK29NC ->BCHCTL = BCH_WR|BCH_RST; memcpy((u_char *)(pRK29NC->buf),(buf+i*0x400),0x400); // only use nandc sram0 if(i==0) memcpy((u_char *)(pRK29NC->spare),(u_char *)(chip->oob_poi + chip->ops.ooboffs),4); - pRK29NC ->BCHCTL = BCH_WR|BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_RDN|FL_BYPASS|FL_START; wait_op_done(mtd,TROP_US_DELAY,0); } - pRK29NC ->chip[0].cmd = NAND_CMD_PAGEPROG; + pRK29NC ->chip[chipnr].cmd = NAND_CMD_PAGEPROG; @@ -655,7 +643,7 @@ int rk29_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page, i pRK29NC ->BCHCTL = BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ; wait_op_done(mtd,TROP_US_DELAY,0); - //rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; + rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; if(i==0) memcpy((u_char *)(chip->oob_poi+ chip->ops.ooboffs),(u_char *)(pRK29NC->spare),4); } @@ -698,7 +686,7 @@ int rk29_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, uint8_ pRK29NC ->BCHCTL = BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ; wait_op_done(mtd,TROP_US_DELAY,0); - //rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; + rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; memcpy(buf+i*0x400,(u_char *)(pRK29NC->buf),0x400); // only use nandc sram0 if(i==0) memcpy((u_char *)(chip->oob_poi+ chip->ops.ooboffs),(u_char *)(pRK29NC->spare),4); @@ -725,12 +713,12 @@ static int rk29_nand_setrate(struct rk29_nand_mtd *info) // some nand flashs have not timing id and almost all nand flash access time is 25ns, so need to fix accesstime to 40 ns - accesstime = 40; + accesstime = 50; info->clk_rate = clkrate; clkrate /= 1000000; /* turn clock into MHz for ease of use */ - if(clkrate>0 && clkrate<=250) + if(clkrate>0 && clkrate<=400) ns= 1000/clkrate; // ns else return -1; diff --git a/drivers/mtd/rknand/Kconfig b/drivers/mtd/rknand/Kconfig index b373b069911a..71618f084d69 100755 --- a/drivers/mtd/rknand/Kconfig +++ b/drivers/mtd/rknand/Kconfig @@ -24,6 +24,12 @@ config RKFTL_PAGECACHE_SIZE help default size is 64MB,and "swap" size is (128 - 64)MB.if you config this size up to 128MB,then "swap" funtion will disable. +config MTD_RKNAND_BUFFER + tristate "RK29 Nand buffer write enables" + depends on MTD_RKNAND + default y + help + config MTD_NAND_RK29XX_DEBUG tristate "RK29 Nand driver debug enables" depends on MTD_RKNAND diff --git a/drivers/mtd/rknand/Makefile b/drivers/mtd/rknand/Makefile index 26555f171403..c4ba9e7c6f9b 100755 --- a/drivers/mtd/rknand/Makefile +++ b/drivers/mtd/rknand/Makefile @@ -6,8 +6,12 @@ obj-$(CONFIG_MTD_NAND_RK29XX) += flash.o obj-$(CONFIG_MTD_NAND_RK29XX) += ftl.o obj-$(CONFIG_MTD_NAND_RK29XX) += rknand_base.o +obj-$(CONFIG_MTD_RKNAND_BUFFER) += rknand_buffer.o + #obj-$(CONFIG_MTD_UBI) += ubi/ $(obj)/flash.o: $(obj)/flash.uu uudecode $(obj)/flash.uu -o $(obj)/flash.o $(obj)/ftl.o: $(obj)/ftl.uu uudecode $(obj)/ftl.uu -o $(obj)/ftl.o +$(obj)/rknand_buffer.o: $(obj)/rknand_buffer.uu + uudecode $(obj)/rknand_buffer.uu -o $(obj)/rknand_buffer.o \ No newline at end of file diff --git a/drivers/mtd/rknand/api_flash.h b/drivers/mtd/rknand/api_flash.h index a3994682867c..05660188326e 100755 --- a/drivers/mtd/rknand/api_flash.h +++ b/drivers/mtd/rknand/api_flash.h @@ -27,6 +27,7 @@ Modify log: ˵ Ã÷:ÉϵçÖ»Ðèµ÷ÓÃÒ»´Î³õʼ»¯¼´¿É ***************************************************************************/ extern int FtlInit(unsigned int nandcBaseAddr,unsigned char pageRemapEn); +extern int FTLInit_WithoutPageRemap(void); extern int FTLInit(void); diff --git a/drivers/mtd/rknand/flash.uu b/drivers/mtd/rknand/flash.uu old mode 100755 new mode 100644 index 80b6662562f1..fd02dbd47bde --- a/drivers/mtd/rknand/flash.uu +++ b/drivers/mtd/rknand/flash.uu @@ -1,5 +1,5 @@ begin 644 flash.o -M?T5,1@$!`0````````````$`*``!``````````````!$2@``````!30````` +M?T5,1@$!`0````````````$`*``!``````````````!\30``````!30````` M`"@`#P`,``0PG^45`-/E'O\OX0`````$,)_EH`"#Y1[_+^$`````-#"?Y30@ MG^6@$)/E`@!1X0``H`,>_R\!O"G3X0(`4N,!`*"3'O\OD:0PD^4#`%#A``"@ M@P$`H),>_R_A`````$Y!3D0@,)_EO!G3X1#`T^48()/EG`$#X)(#`^`#`%#A @@ -56,10 +56,10 @@ M___K`3!%XJ50@^$!4(7BE0``X&/^_^M@,*#C"#"$Y?\P`.($,(3E(#2@X00P MA.44,)_E#3#3Y0``4^,@"*`1!`"$%130C>+P@+WH`````-0PG^430"WI+""3 MY0(`4.$``*`S#P``.C#`D^4`$&+@#`!1X0$`H#,*```Z-""3Y0$0;.`"`%'A M`@"@,P4``#HX,)/E`2!BX`,`4N%``*`C(```*@,`H.-\,)_E`""3Y0(`4N,( -M0(`2!$"3!00PDQ4"3(0"!$2#$(!$A`#-_?_K5#"?Y14$()WE``!2XP$P0N($,(WE^O__&BPPG^4``)3E`!"3Y7``[^8"`%'C!!"3 M!000DQ4`,)$%`#"1%1(PPP<2,,<7`#"!Y1R`O>@`````]T`MZ0!PH.$`0*#C -M`6"@XU!3#.,'`*#AP/__ZT``$.,(```:!&"-Y00PG>4``%/C`3!#X@0PC>7Z +M"F"@XU!3#.,'`*#AP/__ZT``$.,(```:!&"-Y00PG>4``%/C`3!#X@0PC>7Z M__\:`4"$X@4`5.'R__\:_H"]Z/!/+>DT09_E`U`"X@!@E.4%(J#AA52@X0(` M5N,)```:!$"4Y0,`4.,&#*"#"GR$XA)LA.(%4(?@`B"&X`),A.()``"*!P`` MZ@1`E.4(`(#B`7J$X@)LA.(%4(?@`B"&X``$A.`!``#J@`2@X0``A.`#LJ#A @@ -80,7 +80,7 @@ M,*#C`P!3XP,@H.$$``":`0`3XP,@H!,"(*`#@R!BX/\@`N(!P(/B`P"!X'PP M[^;0(,#E@`!3X_'__QH0@+WH9!"?Y?\@H.,`,*#C`4"#X@$`4^,#P*"1`P"! MX'0P[^8"P*"!`B""XH``4^/0P,#EG@ -M0)_E%##4Y0(`4^,T```:3#"4Y0``4^,Q```*`%"@XS:@H.,5CH3B`7"@XQ9@ +M0)_E%##4Y0(`4^,T```:3#"4Y0``4^,Q```*`%"@XS:@H.,5CH3B"G"@XQ9@ MH.-U`._FN/S_ZP`PE.4%`8C@K!"@XP(`4^,(((42!#"4!00PE!4"/(,"A32# M``(T@Q`(H(/E!!"#Y=`@T.$`((/E!'"-Y00@G>4``%+C`7Z__\: M`1"!X@$`@.*P`%'C\O__&@A@@^4`,)3E`@!3XP4``!H$$)3E`#"1Y1(PP^<` @@ -92,500 +92,526 @@ M__\:\(&]Z/!%+>D`<=#E`5"@X0!`H.,!,=#E!\"@X0T``.H,8-#G`S"&X',P M[^8#@-#G#(#`YP-@P.<,H-#G!(#2YPI@AN#_8`;B!F#0YP9@*.`$8,+G`4"$ MX@'`C.(``%7C`5!%XGS`[^;L__\:`1"'X`$QP.4`$<#E\(6]Z$0PG^5P0"WI M`%"@X0%@H.%&WTWB#P"3Z$+/C>($0(WB#P",Z`P@H.$$`*#A$!"@X_[__^L$ -M`*#A!A"@X04@H.'^___K1M^-XG"`O>@```````#@XQ[_+^$``.#C'O\OX?[_ -M_^H$`)_E`!"@X_[__^H``%#T!`"?Y0$0H./^___J``!0]`0`G^4`$*#C_O__ -MZ@``4/3P02WI]72@XP%@H..$`)_E`$"7Y000H.'^___K5!7DY]0QYN?40.'G -M!C"#X!9$H.$&$('@,`"@XY$$`>"0`P#@_O__ZP!0H.$`$*#A2`"?Y?[__^L4 -M0)?E0`"?Y000H.'^___K5!?DY]1*X><&$('@%F2@X04`H.&1!@'@_O__ZP!` -MH.$`$*#A%`"?Y?[__^L$`*#A\(&]Z``````2````(@```#<````00"WI_O__ -MZP`0H.$0`)_E_O__ZPP`G^4`$*#C$$"]Z/[__^I'``````!0]/=/+>G<0)_E -M`%"@XS>PH.,!D*#C=0#OYJQPH./J^__K`#"4Y<``G^4"`%/C"("%$@0PE!4$ -M@)0%"(2#$*PPG^4"C(@"A82(``6A@^#^___K"+"(Y01PB.4$D(WE!&"=Y0`` -M5N,!,$;B!#"-Y?K__QH`$)CE`7"'XG0`G^5Q$._F`1#*Y'$0K^;^___KL`!7 -MX^[__QI<`)_E_O__ZP`PE.4"`%/C!0``&@0@E.4`,)+E%C##YP`PC>4`,(+E -M!0``Z@0PE.4`()/E`""-Y0!@S>4`()WE`""#Y0%0A>($`%7CR___&OZ/O>@` -M````4P```%`!``!X````@````/!!+>GZ'Z#C_O__Z_(Q`.,!($#B`&"@X0,` -M4N'P@;V(`!"@X1`'`N/^___K%'&?Y0!`H.,3$-?E`%"@X0@!G^7^___K!A"@ -MX0`!G^7^___K$S#7Y0H`H.,%$*#AD`,`X`$`0.(%`(#@_O__ZP!@E^4"`%;C -M#@``&@0`4.,!,*#C`V!`@A-&T>=V<._F)C%'X#\P`^*30LKGE0,#X$$/4^,! -M#(4R!1"@,0,`@#(1```Z$@``Z@,`4.,!,*#C`V"@DP%@0((&`*#A`Q"@XQ-& -MT>?^___K=G#OY@<`8.`_``#BD$+*YY4``.#'`%#C`P``BL<`A>(%$*#A_O__ -MZY!"RN?4,N7G2`"?Y0,`5N$'<&.``'"@DQ]P!X(!,(?B%T#$YY4#!>"5`%7C -M$T#$EQ0PG^4$()/E!$""Y00PD^4$$)/E\$&]Z/[__^H`````A0```)@```"I -M````_O__ZO[__^J`P9_E\$]"!@QG^4`,)/E`@!3XP`PH!,PP*`3 -M"`&?%04`H`$&$*`!#```&B4``.J<`@+@#Z!6Y1"`5N4``%+C"J2(X0.`@N(( -M(*"Q0B&@X0*!E><'((/@]Z```4^,"```*`P"@X80DH.'^___K``!6 -MX_"'O0AX,)_E`#"3Y0(`4^,`,*`3,!"@$PX``!H&`*#A!1"@X00BH.'P1[WH -M_O__ZI$"`N`#P(+B``!2XPP@H+%"(:#A`B&5YS(@H.$0($;E(B2@X0\@1N4' -M((/@<\#OY@$``N($`%SAHB^"X`$P@^(``J#A$&"&XL(@H.'K__\Z\(>]Z``` -M`````/__`P!1XW!`+>D`4*#A`4"@X0``X,-P@+W(*!"?Y0(LH..4$B'@_O__ -MZP$`5.,``*`#<("]"`4`H.$"'*#C_O__ZP``H.-P@+WH8`$``!!`+>D"$*#C -M_O__ZW``[^80@+WH$$`MZ0,0H./^___K<`#OYA"`O>@``%+C$$`MZ0!`H.$` -M```*_O__ZP0`H.$0@+WH<$`MZ4A1G^5(,9_E`$"@X7`IE>4#`%+A!@``&@`0 -MH.,"+*#C_O__ZP0`H.&6'H7B92^@XT0``.H"+*#C`!"@X_[__^N\,=7A!##$ -MY2,TH.$%,,3E$C#5Y04!,,3E+C#5Y0(PQ.4O,-7E -M`S#$Y18PU>4&,,3E$S#5Y0@PQ.44,-7E"3#$Y10PU>7_`%/C`#"@`PDPQ`6H -M,)_E#"#3Y0``4N,%```:N#'3X00@@N(&(,3E!##$Y2,DH.$%(,3E`!"@XWP@ -MG^4!,*#A`0"@XPH0Q.4L$)+E!"""X@``4>,*$-05$!.!$0$P@^(*$,05!`!3 -MX_;__QH`(*#C%R#$Y40@@N(0(,3E02"@XQ(@Q.4?(*#C-!"?Y18@Q.4!((+B -M%"#$Y0$@H.,8`(3B%2#$Y7,@@N)*,(/B$S#$Y1$PQ.5P0+WH_O__Z@````!$ -M3D%."````/[__^K0$*#C_O__ZOPQG^4`(*#C\T4$,-T%!3#=%2`P(P(",",2TS+@!],PX!<``%/C"``` -M&@#`C>4`,)WE``!3XP$P0^(`,(WE^O__&@$@@N("`%+CZ___&@!0H..,@9_E -MC)&?Y06@H.$,`)CH`#"3Y0(`4N,$,(WE!##=!04PW173,N`'TS#@%P``4^,/ -M```:?##8Y0``4^,#```*L#C8X3``4^,````*_O__ZP"@C>4`,)WE``!3XP$P -M0^(`,(WE^O__&@%0A>()`%7AY?__&A@QG^5\(-/E``!2XR4```JP*-/A,`!2 -MXR(```H*$-/E``"@XWP`P^4``%'A"P``"KXWT^$!`%/C!0``F@0`H.%`_/_K -M0``0X_O__PH!@*#C`P``ZA`P".,#`%+A$0``"@"`H..T4)_EB&"5Y08`H.$T -M_/_K,`B@X0$`$.,)```*L"G5X08`H.&,$)7E`%#@X_[__^L`@*#A``"@XP`0 -MH.'^___K`0``Z@2`H.$`4*#C``!7XQ<```I@,)_E!@"@X1A@D^40,-/EE@,& -MX`80H.'^___K!A"@X0"@H.$$`*#A_O__ZP``6N$*```:``!5XP<```H$`*#A -M!A"@X?[__^L(`*#A`4"@X080H.'^___KED`DX`!`A^4%`*#A_(>]Z`````"@ -MA@$`\$\MZ1303>(0$(WB#``AY?[__^N$,9_E!""=Y2P`D^4``%+A`%"@,U8` -M`#HPP)/E`@!@X`P`4.$!4*`S40``.C00D^4``&S@`0!0X0)0H#-,```Z.#"3 -MY0`08>`#`%'A1```*D8``.J\&=/A`@!1XT```)JD,)/E`P!2X3T``)H8,9_E -M`'"@XQ!!G^70L*#C!V"@X="0!N,`()/E`:"@XP(`4N,(@(42!("3!00PDQ4" -MC(@"A82(``B$@Q`G``#JQ/G_ZP0`G>5T^__K"+"(Y0`PE.4"`%/C!0``&@0@ -ME.4`,)+E'S##YPPPC>4`,(+E!0``Z@0PE.4`()/E#""-Y0Q@S>4,()WE`""# -MY00PG>4`(*#CL"G$X080H.&^)=3A`P"@X;"8Q.$!<(?BC&"$Y8@PA.47(,3E -MOF?$X7R@Q.7^___K``!0XP``X!,*```:!""=Y1PPE.4#,(+@!#"-Y180U.4( -M`*#C_O__ZP``5^$%`*#AT?__.@``H.,4T(WB\(^]Z`-0H.,0,)_E$!"?Y:`` -MD^4!`%#ALO__&K?__^H`````3D%.1/]'+>D$`(WE`%!1X@00C>(``(45!`"= -MY?[__^M,,I_E""#3Y180T^61`@+@!P!2XU,``,H,(-/E``!2XP4```H8()/E -MO#G3X9(#`^`$()WE`P!2X4H``#H$`)WE_O__ZW<``.HL();E`@!3X0!`H#-V -M```Z,!"6Y0,P8N`!`%/A`4"@,W$``#HT();E`S!AX`(`4^$"0*`S;```.C@0 -MEN4#,&+@`0!3X6<``#H``.#C8P``Z@0@EN4"+(+BA$2"X`(``.H(0(3B!""6 -MY01$@N"@();E!!"=Y0D`4N$%```*O"G6X0(`4N,'``":I""6Y0(`4>$$``": -M"("$Y0`PEN4"`%/C$@``&@L``.H"`%/C6#&?Y0``H`,``*`3!""3!00@DQ4` -M,)(%`#"2%1\PPP4,H,WE#""=Y0`@@^4$()WE`7"'XA4PUN4#,(+@!#"- -MY00``.H`<*#CX&"?Y>"0G^4'H*#AT("@XQ`@UN7,0)_E`@!7X00PG>6M__\Z -M%1#4Y0!@H./0H`;C!G"@X0&`H..1,F/@&```Z@0PG>4`(*#CL"G$X;XEU.$# -M`*#AL*C$X8@PA.47(,3EC'"$Y;YWQ.%\@,3E_O__ZP``4.,&```*``!5XV0P -MGQ4`()45%3#3%9,F9A``8(45"0``ZA4PU.4!8(;B!""=Y0,P@N`$,(WE!1"@ -MX1`PU.4#`%;AX?__.@``H.,0T(WB\(>]Z`-`H.,$`*#A]?C_ZP0`G>6E^O_K -M`#"6Y0(`4^.5__\:D/__Z@````!.04Y$\#"?Y7-`+>D`4*#A`""3Y0%@H.$" -M`%+C!@``&@1`D^4#`%#C!CR@@X`TH)$"3(3B`T"$X`(``.H$,)/E"$"`X@1$ -M@^`%`*#AVOC_ZZ0PG^7_(*#C"""$Y0``H..^)=/A`!"@X1<@P^7^___KD#"@ -MXP@PA.4`,*#C!#"$Y0HP@^($,(WE!""=Y0``4N,!,$+B!#"-Y?K__QH`$)3E -M5#"?Y0`0QN4`$)3E`1#&Y0`0E.4"$,;E`!"4Y0,0QN4`$)3E!!#&Y0`0D^4" -M`%'C!!"3%0`PD142,,<7!```&@,`5>,$$).5`#"1E1(PPY<```"*`#"!Y7R` -MO>@`````#,&?Y0$PH.'P02WI`$"@XP1@G.4$4*#A4"3GYR",H.%0&.?G"$"& -MY0!PG.4$8)SE`@!7XPQ`EN40```:$@#CV^O_J -M`1`!X@%`A..10,'G%4;,YY%0P>>!7X7C&$7+YY)1Q.>34L?G`EN%XQX``.H, -M`-SE``!0XP$``!H#`%?C\(&]"`$0`>+2(.#GD5#!YY%`P>=H$)_E#%"%XQ)2 -MQ.>C(*#ADE+&YY]!P^<2$-'E$EV%XYA"Q^<``%'C`EN%`P0@H`,25M$'`P!7 -MXP8``)H``%#C`E:%`P%(A`.34L8'$#"6Y1\QPN<0,(;E$#"?Y00@D^4,0(+E -M!#"3Y0A0@^7P@;WH`````/!/+>EL0I_E+-!-X@&`H.$H,(WB`K"@X1@@E.4, -M`"/E`Q"@X;PYU.$64-3ED@,#X`,`4.$(,*`C!#"@,Q0PC>7^___K+!"4Y1PP -MG>4!`%/A`$"@,X(``#HP`)3E`Q!AX```4>$!0*`S?0``.C0@E.4!$&#@`@!1 -MX0)`H#-X```Z.`"4Y0$@8N```%+A``#@(W```"IQ``#J!""2Y0(L@N*$)(+@ -M"""-Y0,``.H$()+E"!"$X@$4@N`($(WEM"&?Y;01G^6@`)+E`0!0X04```J\ -M&=+A`@!1XUT``)JD()+E`@!3X5H``)H$`*#A"Z"@X2OX_^L$/*#A`3B#XX4D -MH.$8,(WE")"@X04RH.$0((WE##"-Y0!@H.-8<9_E,0``ZAP`G>4`$*#C``"& -MX/[__^L<`)WE``"&X%_Y_^L),*#A`0"@XP`0H.,%(*#A`*"-Y;?\_^L`,)?E -M`0!5XP,`4Y,%```:!`"@X0$0H.,`(*#C!3"@X6?Z_^L-``#J!1"@X1@`G>57 -M___K!!"7Y0`@E^4(,)'E`@!2XR0PC>4E,-T%)C#=%1`P(^)3,N#G``!3X_;_ -M_QH0()WE``!8XP`@H`,%8(;@`I")X`@@G>4,,)WE``!;XW9@_^8`,*`#`Z"* -MX!`PH.,(,(+E%""=Y80PG^4"`%;AR?__.@`@D^4!$*#C``"@XP(`4N,$(),% -M!""3%0`PD@4`,)(5'S##!Q\PQQ<`,(+E"""@XT@PG^6P*6P&,/AC("#Y8@@@^4```#J``"@XRS0C>+PC[WH`T"@XPP@ -MG^4`$)+E`@!1XXW__QJ'___J`````$Y!3D00@/__W,2?Y?!/+>E$T$WB`H"@ -MX18@W.4<,(WE"##4D`(WED@,#X`<`4^,-``#*###4D`)WE_O__ZPX!`.HD -M`)WEO?G_ZT``$./[__\*9#2?Y0H@T^4``%+C`@``"KXWT^$!`%/CT`#GAP$` -M$.,"```*)`"=Y200C>+^___K-#2?Y200G>4L`)/E``!1X0!@H#/[```Z,,"3 -MY0$`8.`,`%#A`6"@,_8``#HT()/E``!LX`(`4.$"8*`S\0``.C@PD^4`(&+@ -M`P!2X0``X"/I```JZ@``Z@0PD^4"/(/BAC2#X!@PC>4#``#J!#"3Y0@@AN(" -M)(/@&""-Y;@SG^6X(Y_EH`"3Y0(`4.$%```*O"G3X0(`4N/?``":I#"3Y0,` -M4>'<``":C#.?Y0@@T^4!`%+C!P``FKP)T^$0P-/E&""3Y9P``^"2`P/@`P!1 -MX0*@H",````J`:"@XQ00G>4&/*#A`'"@XP$X@^,0<(WE(#"-Y0P0C>4\0Y_E -M"P``ZA8`U.4D,)WE`P"`X&OY_^M``!#C^?__"@P@G>4!<(?B`3"@XQ`PC>6+ -M)(+@#""-Y08`H.%/]__K`0!:XP0``!HD`)WED?C_ZPR0G>4`4*#C8```ZA80 -MU.4!``?B)""=Y2PPE.61("#@`P!0X0`PH#,.```Z,""4Y0``8^`"`%#A`3"@ -M,PD``#HT,)3E``!BX`,`4.$",*`S!```.C@@E.4``&/@`@!0X>;__RH#,*#C -M`""4Y0(`4N,(4(,2!%"4!00@E!4"7(4"@U2%``54@A#^___K$,"=Y3@@C>(\ -M,(WB-!"-X@&0#.(`L*#A5/?_ZSP@G>4``%GC.#"=Y20`E.4#,(+@-""=Y0`` -M"^"2.2G@`)")X+(VU!$)`*`1(S2@$0@PA14%```:NC74X2,TH.$(,(7E#C#4 -MY0``4^,)`*`1=/?_ZP`0H.,$$(7E!!"%Y?\@`.(@.*#A!""%Y2`$H.$$`(7E -M!#"%Y;;__^H``%CC=1#OYA#`H!,`P*`#`B"@XP$`H..5C"S@"3"@X0#`C>6< -M^__K!!"4Y0`@E.4(,)'E`@!2XS`PC>4Q,-T%,C#=%1`P(^)3,N#G``!3X_;_ -M_QH@()WE`A"@XP&;B>(%!(+A`E"%XCC^_^L6L-3E"P!5X>'__SH``%CC"X*( -M$`$`%^,#```:`3"'X@H`4^$1(*`3$```&@HPU.44M,-T%+C#=%1`P(^)3,N#G``!3X_;_ -M_QH8$)WE"""!Y0`@E.4"`%+C!0``&@00E.4`()'E$R##YR@@C>4`(('E!0`` -MZ@0@E.4`$)+E*!"-Y2@PS>4H,)WE`#""Y1`@G>4!,(+B@#8*#C+#"?Y0`@D^4"`%+C%/__&@[__^HD`)_E_O__ZQ`P -MG^4<`)_EI!"3Y?[__^L``*#C[___Z@````!.04Y$$(#__[P```#J````\$\M -MZ0"04^),T$WB"6"@`20`C>48$(WE'""-Y7"@G>7R`0`*^$>?Y1@0G>4<()WE -M#%#4Y1`0C>4``%7C#""-Y7H``!I($(WB"``AY?[__^M`()WE+#"4Y0,`4N$. -M```Z,!"4Y0(@8^`!`%+A`5"%,@D``#HT,)3E`B!AX`,`4N$"4*`S!```.C@0 -ME.4",&/@`0!3X=0!`"H#4*#C@(>?Y04`H.%?]O_K,#"@XP!`H.-``)WEL#C( -MX0APH.&^-=CA!:R@X01@H.$7,,CE`_?_ZQ"`G>5-``#J0`"=Y0`0H.,``(3@ -M_O__ZP`PE^4#`%/C!0``&@`0H.,%`*#A`2"@X0$PH..D^/_K+```Z@H`H.$! -M$*#CE/W_ZPP`E^@($)/E`@!2XS@0C>4Y$-T%.A#=%1`0(>)1$N#G``!1X_;_ -M_QH"`%+CT+"3!2"PDQ42,-?E``!3XSRPC>48```*/"#=Y04@`N(%`%+C!0`` -M&D`0G>4`8.#CK`:?Y0$0A.#^___K#@``ZMNQX^<",$/B`P!;X0H``+I``)WE -M-O;_ZP`PE^5`$)WE`@!3XWP&G^4!$(3@/+"=%=NQY!<+(*#A_O__ZPS`G>4` -M`*#C"#"@X0$@H.,`$*#A`4"$X@#`C>6U^O_K&!"=Y1S`G>4``%'C#!"=Y0(L -MH!,`(*`#``!`,$(WE="#_Y@@VG^4)`%+AK?__ -M.@`@D^4"`%+C:@$`&F4!`.I($(WB`3#`XP&P`.(#`*#A)#`AY?[__^LD()WE -M+#"4Y0,`4N$`4*`S:`$`.C`0E.4"(&/@`0!2X0%0H#-C`0`Z-#"4Y0(@8>`# -M`%+A`E"@,UX!`#HX$)3E`C!CX`$`4^%5`0`J6`$`ZH0@D^4D,)WE`P!2X1<` -M``IT-9_E`!"@XP`@D^5]$,/E`P!2XP<``)JP*-/A,`!2XP0``!H$()/E"#"2 -MY0$&$^,T,(WE^___"CPUG^4P(*#C)`"=Y;`HP^%Z]O_K)`"=Y0`0H./^___K -M!0"@X$L```Z -MA!"3Y2P@D^4"`%'A`$"@,P\``#HP`)/E`1!BX```4>$!0*`S"@``.C0@D^4! -M$&#@`@!1X0)`H#,%```Z.#"3Y0$@8N`#`%+A!$"@(P(``"H#0*#C!0!4X14` -M``H,9)_E!`"@X8+U_^N$`);E+O;_ZP`PEN4"`%/C!""6%0`PDA4?,,<7!``` -M&@,`5.,$():5`#"2E1\PPY<```"*`#""Y04`H.$!$*#C(!"-Y7#U_^L!``#J -M`""@XR`@C>4`8*#C!0R@X0(0H.,48(WE!H"@X;C\_^N40Y_E!G"@X<(``.H( -M$)/E`@!2XS`0C>4Q$-T%,A#=%1`0(>)1$N#G``!1X_;__QH"`%+CT#"3!0(` -M``H#`%+C$#"3!2`PDQ4"((CB1#"-Y0(@:^`)`%+A!0``*A0PG>4"$*#C`0`C -MX@4\H.&`!(/AF_S_ZQ(@U.4``%+C'@``"@`0E.5$,-WE`@!1XU,QX(<(``"* -M!#`#XG,P[^8``%/C`3"@$P(``!H``%OC13#=!=,PX`=S,._F``!3XP!PX!,- -M```:`@!1XT0PG873,>2'!P``B@``6^-$,)WETS'C%P,``!I3%>/GTS'CYP$` -M4^$!,*"Q`P!7X0-PH#$),&C@`F!KX@,`5N$#8*`A!H"(X`D`6.%D```Z``!2 -MXPX``!H4,-3E`0!3XPL``!H%`*#A+/?_ZQ``$.,$```*9`*?Y200G>7^___K -M)`"=Y2?U_^L`P.#CA,"$Y5,``.J\*=3A$!#4Y1@PE.61`@+@DP(#X"0@G>4# -M`%+A`##@,X0PA#5)```Z`#"4Y0(`4^,&```:`P!5XP0@E)4`,)*5'S##ERPP -MC94`,(*5!@``Z@0PE.4`$*#C`""3Y2P@C>4L$,WE+""=Y0`@@^4@()WE``!2 -MXS4``!J$,)3E*""4Y0(`4^$Q```J``!:XP(```H"`%KAA*"$-0,``.H6(-3E -M`2!"X@,`$N$H```:A""4Y2PPE.4#`%+A`%"@,PX``#HP$)3E`B!CX`$`4N$! -M4*`S"0``.C0PE.4"(&'@`P!2X0)0H#,$```Z.!"4Y0)08^`!`%7A`U"@,P10 -MH",%`*#AS_3_ZX0`E.5[]?_K`#"4Y0(`4^,&```:`P!5XP0@E)4`,)*5'S## -MER@PC94`,(*5!@``Z@0PE.4`P*#C`""3Y2@@C>4HP,WE*""=Y0`@@^44()WE -M``"@XPS`G>40,)WE@A"+X'8@[^8`P(WE`+"@XW$0[^96^?_K&!"=Y1P@G>4` -M`%'C$,"=Y88TH!$!,*`!``!2XPP0G>4"8*`!%""=Y09BH!$&$('@`2`BX@P0 -MC>44((WE`\",X!#`C>4)`%CA>#"?Y0P`E#@X__\Z`""3Y0=@H.$"`%+C!0`` -M&@,`5>,)``"*!""3Y0`PDN4?,,/G`@``Z@0@D^4`,)+E'S#'YP`P@N4```#J -M`&#@XP8`H.%,T(WB\(^]Z`-0H.,%`*#AA_3_ZQ0PG^6P&-/AOB73X3``4>,7 -M(,/EH?[_&IS^_^H`````$`$``"0!``!#`0``\$\MZ1303>(`0*#A`X"@X0@0 -MC>4!H*#A#""-Y0*PH.$`<*#C&&&?Y4```.H64-;E!`"@X0LPUN4``%/CA5"@ -M$750[Q8%$*#A_O__ZS@PG>4$`*#A"R"@X0`PC>4%4&'@"A"@X0@`5>$(4*`A -M=5#OY@4PH.'4_?_K`0!PXP"0H.$4```:3,"6Y0``7.,,```*!`"@X0H0H.$+ -M(*#A!3"@X3S_+^$!`'#C`'"@X0!PH!,5```:!!"@X8@`G^7^___K$0``ZH`` -MG^4$$*#A_O__ZPEPH.$,``#J$C#6Y0,P0^(#`%#A"```.DPPEN4``%/C`0`` -M&@0`H.%1]/_K"2"@X4@`G^4$$*#A_O__ZP@PG>4(@&7@!4"$X```4^,,,)WE -MA:2*$'B`[^8``%/C!;*+$```6..\__\:!P"@X130C>+PC[WH`````&0!``"& -M`0``)`$``/!/+>DLT$WB`&"@X4$+H.,D$(WE`H"@X10PC>7^___K`)!0X@2@ -MH!,-```:R#*?Y4%,H.,0H-/EE`H`X/[__^L`D%#B!@``&@0`H.'^___K`)!0 -MX@`PX`,,,(T%G@``"@&@H..0,I_E&""3Y1`0T^62`0?@!P!8X0``H(,!`*"3 -M``!8XP``H`,``%#C`##@`PPPC06.```*O`G3X9`!`>"2`0+@)!"=Y0(`4>$5 -M4-,EC```.@@`H.$%$*#A_O__ZP8`H.$!28GB"(!AX`<0H.'^___K"#"@XP0@ -MH.$`8(WE>(#_Y@8`8>``$*#C_O__Z[`PU.'R#%/C`#"@$Q`PC145```:L#'4 -MX0$P@^)S,/_FL#'$X0``4^,%```:L"#4X0X\0^(!((+B_R`"X@,P@N&P,,3A -M!Q"@X08`H.'^___K`3"@XQ`PC>4'$*#AL`/$X20`G>7^___KL`3$X0`PH.,@ -M0(WE##"-Y4\``.H0,)WE`;"+X@#@X.,``%/C`""@$PH`6^$!```J"`!6X0'@ -MCC('$*#A!3"@X0#@C>7^___K!4"$X`PPG>5!?(?B!6"&X```4.,`,.`3##"- -MY0H`6^$!*8?B"0"$X`4``#H`<*#C"6"@X0=`H.$8D)WE'+"=Y2,``.H(`%3A -MW___.O;__^H4,)WE)`"=Y0``4^,``(?@`R"@$0,``!H0,)WE``!3XP$IBP(@ -M()T5`#"@XPL0H.'^___K`#!0X@$PH!,``%3C`#"@$P``4^,!```*`0!PXR0` -MC16P,)_E`4"$X@0`H.$0$-/E_O__ZP``4>,"```:)`"=Y200C>+^___K0;R+ -MX@5PA^`*`%3A`0``*@@`5^':__\ZE`4$X"0PG>4D$(WB`S"$X`B`9.`#`*#A -M!&"&X'B`_^8D,(WE_O__ZP``6.,'```*`$"@XQR0C>4)<*#A&)"-Y02PH.$& -MD*#A!6"@X;G__^H)`*#A_O__ZPP`G>4LT(WB\(^]Z!P@D^464-/E`@!8X7*` -M_X9M___J`````/-!+>D`8*#A`@N@X_[__^L`0%#B`&#@`S(```H`$*#C92^@ -MX\0`G^4`4.#C_O__ZP8`H.$$$*#A`""@XP$PH.,`4(WE_O__ZQ&`U.40,-3E -M$B#4Y0B$@^$3,-3E%6#4Y0*(B.&(<)_E`XR(X10PU.4DX-3E!C2#X13`U^4< -M$-3E#"#7Y0``4.,`8*`!!6"@$6``G^4``%CA!6"@$0P`7N$%8*`1`@!1X05@ -MH!$2#E/C!6"@$0D``!H``%;C!P``&@00H.%E+Z#CE@Z'XO[__^L(`(?B&!"$ -MXG0@H./^___K!`"@X?[__^L&`*#A_(&]Z&`)````````1$Y!3O!/+>GD2)_E -M1=Y-X@!0H.$,T$WB`!"@XW0@H.,(`(3B_O__ZP`0H.,8(*#C?`"$XO[__^L` -M$*#C%""@XY0`A.+^___K_Q"@XR@@H..H`(3B_O__ZV4OH..6#H3B`!"@X_[_ -M_^L$4(3E`#"@XZ`PA.4`,(7E!#"4Y0`@D^7_`!+C$@``&O\@H.,`((/E!#"4 -MY0`@D^7_(`+B_P!2XPL``!H#(*#C`""$Y0(JH.,`((/E!#"4Y1\L0N(`$)/E -M`@H1XV`QDQ53..,7`#"$%0,``.H8.)_E$""@XP(0H.,`$(/E"#B?Y000D^4` -M(('E,A"@XP`@D^43$,/E`@!2XPH``!KL!Y_EY&>?Y4%.C>+^___K"$"$X@!P -MH.,7H*#C!E"@X="WG^4&@*#A!@``Z@,`4N/$!Y\%\O__"O[__^OZ/Z#CDP`` -MX.[__^IW`._F!!"@X?[__^L"X-3E`Y#4Y0<0H.$$P-3E`"#4Y0$PU.6,!Y_E -M`."-Y0`2C>G^___K`2#4Y0`PH.,#`-OG?Y0,Q@.`` -M`-3E(#"3Y9@`4.,L,(7E`@``&MX`4N,"):`#+""%!0$PH.,!H*#A$##(Y0(` -M`.H!,(/B&`!3X^K__QH!<(?B+""5Y2@PF.4$`%?C$$"$X@10A>(#,(+@*#"( -MY=+__QKL)I_E`#"@XQC$W>4`$.#C\`:?Y100PN4#$-#G,H```*&A3=Y0+`H.,``*#C`T`"XE'AX><1X,/E````ZG[`[^8!,(#B -M!`!0X8S@H.%S`._F^?__N@#FG^52(N'G@`"@XP`PH.,6P,[E````ZH``H.$! -MP(/B`@!3X7PP[^;Z__^ZU#6?Y0.0`>(4(-/E'`"#Y0$`4N,!((("!P``"@$@ -MH.-1$N'G$A&@X7$0[^8($,/E`@!1XP8``)H"((+@""##Y0,``.H!(*#C%B## -MY1\@@N(<((/E@$6?Y0`@H.,4,-3E3""$Y0(`4^,(4-3E!0``&ADTW>7>`%/C -M`@``&O[__^ML-9_E3#"$Y4PUG^41(-/E`@!2XP,``!H4(-/E``!2XU`EGP5, -M((,%+#6?Y180T^5,,)/E%#"-Y94!`^`'`%/C`@``B@@`H./^___K`%"@X01% -MG^5U`._F$`"-Y19PU.4<,)3E!Q"@X9<``N`#`*#ADP4#X!4@Q.48,(3E_O__ -MZP<0H.$@`(3E+`"4Y?[__^L`$.#CO!G$X3`YH.%!#HWB)#"$Y0@`@.+^___K -M*#"4Y0``4^,,```:%##4Y?\`4^,&```*`3&@XQ80U.4#`*#A+#"$Y?[__^LP -M":#A)`"$Y70TG^4!(*#C$"##Y6ATG^4`@*#C&*"-X@"PX..&3XWB`#"7Y0(` -M4^,.`*`#&`"@$_[__^L<`)?E"A"@X0`@H.,",*#C`+"-Y9`(`.#^___K``!0 -MXPT```H`,)?E`@!3XP@`H`,0`*`3_O__ZQP`E^4*$*#A`""@XP(PH.,`L(WE -MD`@`X/[__^L``%#CKP``&@$`VN4`,-KE`A#:Y0,@VN4`-(/A`3B#X0(\@^'H -M(Y_E`@!3X:4``!H+(-3E4@L$XPHPU.4"-(/A``!3X9\``!KM,=3E$B#7Y0,` -M4N$!```*``!3XYD``!J,(8((/E'""#Y;\N0N(3$,/EF!"! -MXA4@P^4@$(/E%B##Y?@QG^44(-/E!`!2XP$`4A,"```*%C#3Y0\`4^,"``": -MV#&?Y0$@H.,.(,/ES#&?Y10@T^4!`%+C!0``&A80T^4(`%'C`@``BAD4W>71 -M`%'C#R##%:0QG^7M(=3EF,"3Y90`D^4H$)/E``",X!(@P^4!`%#A`(#@(P"` -MH#,``%+C!0``&A0@T^4!`%+C\2"@`[8FPP&((9\%LB;#`5PQG^43(-/E/`!2 -MXSP@H(,3(,.%2#&?Y1,@T^4G`%+C"```BA0@T^4"`%+C)B""`A,@PP4#``#J -M`8"(XC(`6.,P__\:`(#@XQ0QG^4`,)/E`@!3XPP!GP4%```*`P!3XP@!GP4" -M```*_O__Z_H_H..3``#@_O__Z^0PG^4((-/E`0!2XP,``)H/,-/E``!3XP%0 -MA0*E4*`!Q$"?Y1"@A.(8,)3E$'#4Y90`E.63!0+@`0!`XI,'!^`4,)WEO%G$ -MX4PPA.4'$*#A`3!"X@<`@."D,(3E_O__ZY@@E.4'$*#A`2!"XI<``^`'`(+@ -ME#"$Y?[__^N7``?@$@#4Y9APA.7^___K$"#4Y1@0E.4`,*#C*#"$Y0-0H.&1 -M`@3@+#"6Y000H.$``%/B`@``"O[__^N4``#@+`"&Y2PPEN4$8(;B"@!6X0-0 -MA>#S__\:$#"?Y0@`H.$H4(/E7-"-X@';C>+PC[WH`````/!)`@`(````4#0# -M`*E<0Y_E+-!-X@&@H.$"D*#A -M`&"@X0PPC>41,-3E`0!3X\L``)H4$-3E``!1X\@``!K^___K`""4Y0,`4N,$ -M``":!!"4Y0@PD>4!!A/C)#"-Y?O__PH(,Y_E+`"3Y0``5N$`4*`S#@``.C#` -MD^4&`&#@#`!0X0%0H#,)```Z-!"3Y0``;.`!`%#A`E"@,P0``#HX,)/E`%!A -MX`,`5>$#4*`S!%"@(P(`4N.T,I_E!@``&@1`D^4$`%7C!CR@`X4TH!$"3(3B -M`T"$X`(``.H$,)/E"$"%X@1$@^`%`*#AJ?#_ZP`PH..BP*#C!0"@XQ`0C>(( -M`%/C","$Y0,@H!,`(*`#!""$Y3LN@Q(2(*`#`2""$O\@`A($((3E'`"-Y1P@ -MG>4``%+C`>!"XAS@C>7Z__\:`."4Y0/@P>,$$),5`#"1%1(PQQ<$```:`P!5XP,``(H$$)/E`#"1Y1(PP^<`,('E -MY'&?Y0"`H.,%`*#A?_#_Z]@AG^4)$*#C`#"@XY$H(>`(`%/CH2"@XP@@A.4# -M(*`3`""@`P0@A.4[+H,2`2""$A(@H`/_(`(2!""$Y1`@C>(#(-+G<@"OYM`@ -MT>$`(&+@`""$Y04@H.,<((WE'""=Y0``4N,!`$+B'`"-Y?K__QH!,(/B`1"! -MX@D`4^/C__\:`#"7Y0(`4^,&```:`P!5XP00EY4`,)&5$C##ER`PC94`,(&5 -M!0``Z@0PE^4`$)/E(!"-Y2`@S>4@()WE`""#Y0H0H.$)(*#A##"=Y08`H.$` -MP.#C`,"-Y;[Y_^L`$*#C`+"@X08`H.'^___K`0![XP(``!H!@(CB$P!8X[W_ -M_QH%`*#A/?#_ZP`PH..AP*#C$`"-X@40H.,(`%/C","$Y0,@H!,`(*`#!""$ -MY3LN@Q(2(*`#`2""$O\@`A($((3ETR"0X0`@A.4<$(WE'""=Y0``4N,!<$+B -M''"-Y?K__QH!,(/B"0!3X^K__QIH,)_E`!"3Y0(`4>,$$),5`#"1%1(PQQ<$ -M```:`P!5XP00DY4`,)&5$C##EP```(H`,('E`0![XPD``!H&`*#A"A"@X0D@ -MH.$,,)WE`,"@XP#`C>6$^?_K`+"@X0```.H`L.#C"P"@X2S0C>+PC[WH```` -M`(````#P3RWI+-!-X@"@H.$,$(WE`!"@XQ0PC>40((WE_O__Z[0RG^4L$)/E -M`0!:X0!`H#,.```Z,`"3Y0H08>```%'A`4"@,PD``#HT()/E`1!@X`(`4>$" -M0*`S!```.C@PD^4!0&+@`P!4X0-`H#,$0*`C9#*?Y0`@D^4"`%+C!@``&@10 -MD^4$`%3C!CR@`X0TH!$"7(7B`U"%X`(``.H$,)/E"%"$X@54@^`P,I_E`8"@ -MXP1PH.$$,8/@&#"-Y1A"G^4`8*#C'("-Y0<`H.$8L)WET>__ZS8PH.,$`I_E -M!A"@X0@PA>6L@*#C_O__Z_0QG^4&D8/@!("%Y=`@V>'0,-OAY`&?Y0,P@N`` -M,(7ET##;X=`0V>$#$('@<1#OYO[__^L!,*#C(#"-Y2`PG>4``%/C`2!#XB`@ -MC>7Z__\:`8"(X@&PB^*P`%CC`9")XNC__QJ8`9_E"#"-Y?[__^L6(*#C"""% -MY0`@E.4(,)WE`@!2XP8``!H#`%?C!!"4E0`@D943(,.7)""-E0`@@94%``#J -M!""4Y0`0DN4D$(WE)##-Y20PG>4`,(+E#!"=Y0H`H.$0()WE`,#@XQ0PG>4` -MP(WE"_G_ZP`0H.,`D*#A"@"@X?[__^L!`'GC`P``"@4`5N,'0*#A%0``F@H` -M`.H!8(;B"@!6X[/__QH<@)WE\`"?Y0@0H.'^___K``!8XP&`2!*I__\:!T"@ -MX;PPG^42,-/E#0!3XP0@H(,"(*"3`S!BX`,`6>$!```Z"@"@X8KO_^L$`*#A -M=.__ZY`0G^6L,*#C`0"@XP01@>`V(*#C"""%Y00PA>70(-'A`""%Y2``C>4@ -M()WE``!2XP'`0N(@P(WE^O__&@$P@^(!$('BL`!3X_+__QI`,)_E%A"@XP@0 -MA>4`$)/E`@!1XP00DQ4`,)$5$C#'%P0``!H#`%3C!!"3E0`PD942,,.7```` -MB@`P@>4)`*#A+-"-XO"/O>@`````4`$``,4!```L`0``>````(````#D`0`` -M[)BMP2P'((EU=GAY.CP```$````"````!``` -M``0````(````!`````0````(````$````"````!`````"````!`````@```` -M0````(```````0``0````(```````0````(````!`````0````+W^/?W]_CY -M^0KW^??W^/G[^PKX^OCX^?K\_`KY^_GY^OO]_0KZ_/KZ^_S^_@K[_?O[_/W_ -M_PK\_OS\_?X```K\__W\_O\!`0K\`/[\_P`"`@K_`?__``$#`PH`!````00$ -M!`H!`P`!`@,%!0H"!``"`P0&!@H"!0$"!`4'!PH"!@("!08("`H#!P,#!@<) -M"0H$"`0$!P@,"@H%"04%"`D-"PH&"@8&"0H.#`H````"```#!00`!@@&``@+ -M"``*#@H`_OOZ`/SV]0#Y\N\`]N[J``#IY`>Q`8&PL%^$`````):R`8&PL*\! -M``````````"PL+"`$````+"PL(`@````L+"P@&0```"PL+"`D````+"PL(`, -M`0``L+"P@"0!``"PL+"`=`$``+"PJ(#P`0``L+"L@,0"``"PL*J`4`,``+"P -ML(#<`P``K`^Q@#P&``"L#[&`[`<``+"K!(!L"0``J`.Q@$P*``"K![&`F`H` -M`+"PKX#<"P``L+"P@,0,``"PL*B`!`X```````#T#@``L+"P@/@.``"PL+"` -M_`X``+"PK(!X#P``L%^$@/`/``"J/P6`0!```+"PL(!($```L+"P@%`0``"P -ML+"`5!```+"PL(!D$```L+"P@'00``"PL+"`A!```+"PK(`L$0``L+"H@%@1 -M``"O![&`5!(``+"PK("L$P``L+"P@+`3``"PL+"`M!,``+"PKH!$%0``L+"J -M@)`5``"PL*B`I!4``+"PJ("X%0``L+"H@-05``"PL*J`-!<``+"PL(`X%P`` -ML+"P@$`7``"N`[&`3!D``+"O!(#T&@``K@^Q@&P=``"J`[&`:!X``+"PK("` -M'P``L*\*@`0B``"PKQ"`_"8``+"O$H`P+P``L*\$@(0P``"PKPJ`A#,``*P# -ML8"`-```#````)@]``"PKPJ`"$$``+"O"H!\3@,$504)!RTL>S@7#1<10U)5 -M7T%03$Q?0T]..B`E>`H`07)M4&QL.B`E9"!-2'H*`$-255]#3$M314PP7T-/ -M3CH@)7@*`$%H8D-L:SH@)60@34AZ"@!!2$(@/25D($U(>@`\-3Y(>6YI>$=E -M=%)E8612971R>41E9F%U;'0@5F%L=64@.B``/#4^("5X(``\-3X*`$%C8V5S -M`H`9T9L87-H26YF;RYS>7-);F9O+G-Y"P@97)R;W(@8FET -M/25D"@`\-3YE2!E`H`1FQA`H`1FQA'1A -M8@`N&ED>``N``#H!@``#0````$````$ -M````"````"4````!`````P`````````T1```5`$`````````````!``````` -M```K````"`````,`````````B$4``/0*``````````````0`````````,``` -M``$````"`````````(A%```8```````````````$`````````#\````!``!P -M@@````````"@10``V`$```$`````````!``````````[````"0`````````` -M````4&4``/@!```-````!@````0````(````2@````$````"`````````'A' -M```0```````````````$`````````%(````!````,@````````"(1P```P(` -M`````````````0````$```!A`````0``````````````BTD``!(````````` -M``````$`````````:@````,``'```````````)U)```K```````````````! -M`````````!$````#``````````````#(20``>@```````````````0`````` -M```!`````@``````````````G$P``+`,```.````@@````0````0````"0`` -M``,``````````````$Q9```;!0`````````````!```````````````````` -M```````````!```````````````$`/'_`````````````````P`!```````` -M``````````,``P`````````````````#``0`"0`````````````````!``P` -M```,`````````````0`````````````````#``4``````````````````P`& -M``D````0`````````````0`,````'`````````````$`"0```"`````````` -M```!``P```!<`````````````0`)````9`````````````$`#````(P````` -M```````!``D```"0`````````````0`,````"`$```````````$`"0````P! -M```````````!``P````@`0```````````0`/````)`$``%`````"``$`"0`` -M`"0!```````````!``P```!P`0```````````0`7````=`$``'P````"``$` -M"0```'0!```````````!``P```#L`0```````````0`G````\`$``-0````" -M``$`"0```/`!```````````!``P```#``@```````````0`Z````Q`(``(P` -M```"``$`"0```,0"```````````!``P```!,`P```````````0!+````4`,` -M`(P````"``$`"0```%`#```````````!``P```#8`P```````````0!;```` -MW`,``&`"```"``$`"0```-P#```````````!``P````X!@```````````0!H -M````/`8``+`!```"``$`"0```#P&```````````!``P```#H!P`````````` -M`0!U````[`<``(`!```"``$`"0```.P'```````````!``P```!H"0`````` -M`````0"(````;`D``.`````"``$`"0```&P)```````````!``P```!("@`` -M`````````0`)````3`H```````````$`F````)@*``!$`0```@`!``D```"8 -M"@```````````0`,````V`L```````````$`"0```-P+```````````!``P` -M``"L#````````````0`)````Q`P```````````$`#``````.```````````! -M``D````$#@```````````0`,````\`X```````````$`"0```/0.```````` -M```!``D```#X#@```````````0`)````_`X```````````$`"0```'@/```` -M```````!``D```#P#P```````````0`,````/!````````````$`"0```$`0 -M```````````!``D```!($````````````0`)````4!````````````$`"0`` -M`%00```````````!``P```!@$````````````0`)````9!````````````$` -M#````'`0```````````!``D```!T$````````````0`,````@!`````````` -M``$`"0```(00```````````!``P````<$0```````````0`)````+!$````` -M``````$`#````%`1```````````!``D```!8$0```````````0`,````0!(` -M``````````$`"0```%02```````````!``P```"<$P```````````0`)```` -MK!,```````````$`"0```+`3```````````!`*@```"T$P``D`$```(``0`) -M````M!,```````````$`#````#P5```````````!``D```!$%0`````````` -M`0`,````C!4```````````$`"0```)`5```````````!``D```"D%0`````` -M`````0`)````N!4```````````$`"0```-05```````````!``P````H%P`` -M`````````0`)````-!<```````````$`"0```#@7```````````!``D```!` -M%P```````````0`,````1!D```````````$`"0```$P9```````````!``P` -M``#L&@```````````0`)````]!H```````````$`#````&0=```````````! -M``D```!L'0```````````0`,````9!X```````````$`M0```&@>```8`0`` -M`@`!``D```!H'@```````````0`,````?!\```````````$`"0```(`?```` -M```````!``P```#X(0```````````0`)````!"(```````````$`#````.@F -M```````````!`,P```#\)@``-`@```(``0`)````_"8```````````$`#``` -M`"`O```````````!``D````P+P```````````0`,````=#````````````$` -M"0```(0P```````````!``P```"`,P```````````0`)````A#,````````` -M``$`#````'0T```````````!``D```"`-````````````0`,````<#T````` -M``````$`"0```)@]```````````!``P`````00```````````0`)````"$$` -M``````````$`#````.1#```````````!``````````````````,`"`#:```` -M`````!`````!``@`#``````````````````(``````````````````,`"0`, -M``````````````````,``````````````````P`*``````````````````,` -M"P#F`````````!`````2``$`]P``````````````$`````X!```0````$``` -M`!(``0`>`0``(````$0````2``$`+@$``&0````L````$@`!`#X!``"0```` -M?````!(``0!%`0``#`$``!@````2``$`3@$`````````````$````%\!```` -M`````````!````!M`0``3`H``$P````2``$`@@$``-P+``#H````$@`!`(\! -M``#$#```0`$``!(``0"F`0``!`X``/`````2``$`OP$`````````````$``` -M`-8!``#T#@``!````!(``0#G`0``^`X```0````2``$`\@$``/P.``!\```` -M$@`!``0"``!X#P``>````!(``0`4`@``\`\``%`````2``$`*`(``$`0```( -M````$@`!`#4"``!($```"````!(``0!$`@``4!````0````2``$`5`(````` -M````````$````&D"``!4$```$````!(``0"&`@`````````````0````C@(` -M`&00```0````$@`!`)H"``!T$```$````!(``0"S`@``A!```*@````2``$` -MO0(`````````````$````,0"```L$0``+````!(``0#,`@``6!$``/P````2 -M``$`Y0(``%02``!8`0``$@`!`/0"``"L$P``!````!(``0#_`@`````````` -M```0````!@,``+`3```$````$@`!`!$#`````````````!`````8`P``1!4` -M`$P````2``$`*@,``)`5```4````$@`!`#P#``"D%0``%````!(``0!,`P`` -MN!4``!P````2``$`5P,`````````````$````%X#``#4%0``8`$``!(``0!L -M`P``-!<```0````2``$`=0,`````````````$````'L#```X%P``"````!(` -M`0"&`P`````````````0````D`,``$`7```,`@``$@`!`)X#```````````` -M`!````"R`P`````````````0````P0,`````````````$````,X#``!,&0`` -MJ`$``!(``0#G`P``]!H``'@"```2``$`]P,``&P=``#\````$@`!``,$``"` -M'P``A`(``!(``0`6!```!"(``/@$```2``$`*`0``#`O``!4`0``$@`!`#H$ -M`````````````!````!*!```A#`````#```2``$`6`0`````````````$``` -M`&8$``"$,P``_````!(``0!V!```@#0``!@)```2``$`@`0```A!``#X`@`` -M$@`!`)$$``"8/0``<`,``!(``0"D!`````````@````1``,`M00```@````8 -M````$0`#`,`$```@````8````!$``P#+!```+`$``"@````1``,`U00``(`` -M``"K````$0`#`-X$``#0````@````!$`!`#K!````````-`````1``0`]@0` -M`&`)``"4`0``$0`$``,%``!@`0````@``!$`!``.!0``4`$``!`````1``0` -M`&9L87-H+F,`)&$`)&0`1FQA7!A7-00!&;&%S:$-M9$EN:70`0G5I;&1& -M;&%S:$QS8E!A9V5486)L90!&;&%S:%-E=%)E8612971R>41E9F%U;'0`7U]A -M96%B:5]U;G=I;F1?8W!P7W!R,0!&;&%S:%AF97)#;VUP25-2`$9L87-H4D)) -M4U(`3D%.1%]20S1?2V5Y4V5T=7``3D%.1%]20S1?0VEP:&5R`$=E=$ED8FQO -M8VM$871A3F]28S0`1FQA5=R:71E0V%C:&5%;@!&5$Q?34-026YI=%]7 -M:71H;W5T4&%G95)E;6%P`$9T;$EN:70`1E1,7TU#4$EN:70`1E1,26YI=%]7 -M:71H;W5T4&%G95)E;6%P`$=E=$%(0D-,2P!P6YI -M>$=E=%)E8612971R>41E9F%U;'0`1FQA0!M96UC<'D`1V5T261";&]C:U-Y0!R:TYA;F1?8V]N9%]R97-C:&5D -M`$9L87-H4')O9T5R``#$$```'(H``-00```< -MG@``Y!```!R>````$0``'(H``!`1`````#P$0``')X``$`2```"!```1!(```)^``!($@`` -M`@0``$P2```"?@``4!(```)^``!<$@``'(H``'P2`````"@ -M$@``')X``+P2`````!`*0``'+```/@I``````@+P```@0``"0O```" -M?@``*"\```)^```L+P```GX``'@O`````#\+P``')X``#@P -M```#D``!RY``#\.0``'+D``%@Z`````!@0@``')X``-A"`````#D0P```@0``.A#```"!```[$,```)^``#P0P```@,``/1#```"?@`` -M^$,```)^``#\0P```GX````````J`@````````"#```(````*@(``!`````J -M`@``&````"H"```@````*@(``"@````J`@``,````"H"```X````*@(``$`` -M```J`@``2````"H"``!0````*@(``%@````J`@``8````"H"``!H````*@(` -M`'`````J`@``>````"H"``"`````*@(``(@````J`@``D````"H"``"8```` -M*@(``)@`````CP``G````"H'``"@````*@(``*@````J`@``L````"H"``"X -M````*@(``,`````J`@``R````"H"``#0````*@(``-@````J`@``X````"H" -M``#H````*@(``/`````J`@``^````"H"`````0``*@(```@!```J`@``$`$` -M`"H"```8`0``*@(``"`!```J`@``*`$``"H"```P`0``*@(``#@!```J`@`` -M0`$``"H"``!(`0``*@(``%`!```J`@``6`$``"H"``!@`0``*@(``&@!```J -M`@``<`$``"H"``!X`0``*@(``(`!```J`@``B`$``"H"``"0`0``*@(``)@! -M```J`@``H`$``"H"``"H`0``*@(``+`!```J`@``N`$``"H"``#``0``*@(` -9`,0!```J!P``R`$``"H"``#0`0``*@(````` +M`*#A!A"@X04@H.'^___K1M^-XG"`O>@`````*#"?Y4P@D^7_),+C#R;"XU4D +M@N,%)H+C3""#Y5`@D^4#(,+C`2""XU`@@^4>_R_A`(``]0``X.,>_R_A``#@ +MXQ[_+^'^___J!`"?Y0`0H./^___J``!0]`0`G^4!$*#C_O__Z@``4/3P02WI +M]72@XP%@H..$`)_E`$"7Y000H.'^___K5!7DY]0QYN?40.'G!C"#X!9$H.$& +M$('@,`"@XY$$`>"0`P#@_O__ZP!0H.$`$*#A2`"?Y?[__^L40)?E0`"?Y000 +MH.'^___K5!?DY]1*X><&$('@%F2@X04`H.&1!@'@_O__ZP!`H.$`$*#A%`"? +MY?[__^L$`*#A\(&]Z``````3````)````#H```!(,)_E$$`MZ4P@D^7_),+C +M#R;"XU4D@N,%)H+C3""#Y5`@D^4#(,+C`2""XU`@@^7^___K`!"@X10`G^7^ +M___K$`"?Y0`0H.,00+WH_O__Z@"``/5+``````!0]$@PG^400"WI3""3Y?\D +MPN,/)L+C522"XP4F@N-,((/E4""3Y0,@PN,!((+C4""#Y?[__^L`$*#A%`"? +MY?[__^L0`)_E`!"@XQ!`O>C^___J`(``]4L``````%#T]T\MZ=Q`G^4`4*#C +M-["@XPJ0H.-U`._FK'"@X[[[_^L`,)3EP`"?Y0(`4^,(@(42!#"4%02`E`4( +MA(,0K#"?Y0*,B`*%A(@`!:&#X/[__^L(L(CE!'"(Y020C>4$8)WE``!6XP$P +M1N($,(WE^O__&@`0F.4!<(?B=`"?Y7$0[^8!$,KD<1"OYO[__^NP`%?C[O__ +M&EP`G^7^___K`#"4Y0(`4^,%```:!""4Y0`PDN46,,/G`#"-Y0`P@N4%``#J +M!#"4Y0`@D^4`((WE`&#-Y0`@G>4`((/E`5"%X@0`5>/+__\:_H^]Z`````!8 +M````4`$``'T```"%````\$$MZ?H?H./^___K\C$`XP$@0.(`8*#A`P!2X?"! +MO8@`$*#A$`<"X_[__^L4<9_E`$"@XQ,0U^4`4*#A"`&?Y?[__^L&$*#A``&? +MY?[__^L3,-?E"@"@XP40H.&0`P#@`0!`X@4`@.#^___K`&"7Y0(`5N,.```: +M!`!0XP$PH.,#8$""$T;1YW9P[^8F,4?@/S`#XI-"RN>5`P/@00]3XP$,A3(% +M$*`Q`P"`,A$``#H2``#J`P!0XP$PH.,#8*"3`6!`@@8`H.$#$*#C$T;1Y_[_ +M_^MV<._F!P!@X#\``.*00LKGE0``X,<`4.,#``"*QP"%X@40H.'^___KD$+* +MY]0RY>=(`)_E`P!6X0=P8X``<*"3'W`'@@$PA^(70,3GE0,%X)4`5>,30,27 +M%#"?Y00@D^4$0(+E!#"3Y000D^7P0;WH_O__Z@````"*````G0```*\```#^ +M___J_O__ZH#!G^7P1RWI`D"@X0`@G.4#<`'B`("@X2!@G>4"`%+C!!"G__SKPA[WH``!3XP(```H#`*#AA"2@X?[__^L``%;C\(>] +M"'@PG^4`,)/E`@!3XP`PH!,P$*`3#@``&@8`H.$%$*#A!"*@X?!'O>C^___J +MD0("X`/`@N(``%+C#""@L4(AH.$"(97G,B"@X1`@1N4B)*#A#R!&Y0<@@^!S +MP._F`0`"X@0`7.&B+X+@`3"#X@`"H.$08(;BPB"@X>O__SKPA[WH```````` +M__\#`%'C<$`MZ0!0H.$!0*#A``#@PW"`O<@H$)_E`BR@XY02(>#^___K`0!4 +MXP``H`-P@+T(!0"@X0(A@`0``$$`MZ0(0H./^___K +M<`#OYA"`O>@00"WI`Q"@X_[__^MP`._F$("]Z```4N,00"WI`$"@X0````K^ +M___K!`"@X1"`O>AP0"WI2%&?Y4@QG^4`0*#A<"F5Y0,`4N$&```:`!"@XP(L +MH./^___K!`"@X98>A>)E+Z#C1```Z@(LH.,`$*#C_O__Z[PQU>$$,,3E(S2@ +MX04PQ.42,-7E!S#$Y2PPU>4`,,3E+3#5Y0$PQ.4N,-7E`C#$Y2\PU>4#,,3E +M%C#5Y08PQ.43,-7E"##$Y10PU>4),,3E%##5Y?\`4^,`,*`#"3#$!:@PG^4, +M(-/E``!2XP4``!JX,=/A!"""X@8@Q.4$,,3E(R2@X04@Q.4`$*#C?""?Y0$P +MH.$!`*#C"A#$Y2P0DN4$((+B``!1XPH0U!40$X$1`3"#X@H0Q!4$`%/C]O__ +M&@`@H.,7(,3E1"""XA`@Q.5!(*#C$B#$Y1\@H.,T$)_E%B#$Y0$@@N(4(,3E +M`2"@XQ@`A.(5(,3EC^___J`````$1.04X( +M````_O__ZM`0H./^___J!#*?Y63`H./W12WI`$"@X0%PH.$#`)/H`""@XP`P +MD>4"`%#C!#"-Y00PW04%,-T5(#`C`@(P(Q+3,N`'TS#@%P``4^,(```:`,"- +MY0`PG>4``%/C`3!#X@`PC>7Z__\:`2""X@(`4N/K__\:F%&?Y0!@H..4H9_E +M`8"@XPP`E>@`,)/E`@!2XP0PC>4$,-T%!3#=%=,RX`?3,.`7``!3XP\``!I\ +M,-7E``!3XP,```JP.-7A,`!3XP````K^___K`("-Y0`PG>4``%/C`3!#X@`P +MC>7Z__\:`6"&X@H`5N'E__\:(#&?Y7P@T^4``%+C)@``"K`HT^$P`%+C(P`` +M"@H0T^4``*#C?`##Y0``4>$+```*OC?3X0$`4^,%``":!`"@X13\_^M``!#C +M^___"@%0H.,#``#J$#`(XP,`4N$2```*`%"@X[R`G^6(8)CE!@"@X0C\_^LP +M5:#A`5`5X@2`H`$,```*L"G8X08`H.&,$)CE`%#@X_[__^L`@*#A``"@XP`0 +MH.'^___K`@``Z@2`H.$`4*#C`&#@XP``5^,7```*8#"?Y08`H.$88)/E$##3 +MY98#!N`&$*#A_O__ZP80H.$`H*#A!`"@X?[__^L``%KA"@``&@``5>,'```* +M!`"@X080H.'^___K"`"@X0%`H.$&$*#A_O__ZY9`).``0(?E!0"@X?Z%O>@` +M````H(8!`/!/+>D4T$WB$!"-X@P`(>7^___KA#&?Y00@G>4L`)/E``!2X0!0 +MH#-6```Z,,"3Y0(`8.`,`%#A`5"@,U$``#HT$)/E``!LX`$`4.$"4*`S3``` +M.C@PD^4`$&'@`P!1X40``"I&``#JO!G3X0(`4>-```":I#"3Y0,`4N$]``": +M&#&?Y0!PH.,009_ET+"@XP=@H.'0D`;C`""3Y0&@H.,"`%+C"("%$@2`DP4$ +M,),5`HR(`H6$B``(A(,0)P``ZI;Y_^L$`)WE1OO_ZPBPB.4`,)3E`@!3XP4` +M`!H$()3E`#"2Y1\PP^<,,(WE`#""Y04``.H$,)3E`""3Y0P@C>4,8,WE#""= +MY0`@@^4$,)WE`""@X[`IQ.$&$*#AOB74X0,`H.&PF,3A`7"'XHQ@A.6(,(3E +M%R#$Y;YGQ.%\H,3E_O__ZP``4.,``.`3"@``&@0@G>4<,)3E`S""X`0PC>46 +M$-3E"`"@X_[__^L``%?A!0"@X='__SH``*#C%-"-XO"/O>@#4*#C$#"?Y1`0 +MG^6@`)/E`0!0X;+__QJW___J`````$Y!3D3_1RWI!`"-Y0!04>($$(WB``"% +M%00`G>7^___K3#*?Y0@@T^46$-/ED0("X`<`4N-3``#*#"#3Y0``4N,%```* +M&""3Y;PYT^&2`P/@!""=Y0,`4N%*```Z!`"=Y?[__^MW``#J+""6Y0(`4^$` +M0*`S=@``.C`0EN4#,&+@`0!3X0%`H#-Q```Z-""6Y0,P8>`"`%/A`D"@,VP` +M`#HX$);E`S!BX`$`4^%G```Z``#@XV,``.H$();E`BR"XH1$@N`"``#J"$"$ +MX@0@EN4$1(+@H""6Y000G>4)`%+A!0``"KPIUN$"`%+C!P``FJ0@EN4"`%'A +M!```F@B`A.4`,);E`@!3XQ(``!H+``#J`@!3XU@QG^4``*`#``"@$P0@DP4$ +M(),5`#"2!0`PDA4?,,,''S#'%P`P@N5!``#J!""6Y0`PDN4?,,/G##"-Y0`P +M@N4%``#J!#"6Y0`@D^4,((WE#*#-Y0P@G>4`((/E!""=Y0%PA^(5,-;E`S"" +MX`0PC>4$``#J`'"@X^!@G^7@D)_E!Z"@X="`H.,0(-;ES$"?Y0(`5^$$,)WE +MK?__.A40U.4`8*#CT*`&XP9PH.$!@*#CD3)CX!@``.H$,)WE`""@X[`IQ.&^ +M)=3A`P"@X;"HQ.&(,(3E%R#$Y8QPA.6^=\3A?(#$Y?[__^L``%#C!@``"@`` +M5>-D,)\5`""5%14PTQ63)F80`&"%%0D``.H5,-3E`6"&X@0@G>4#,(+@!#"- +MY040H.$0,-3E`P!6X>'__SH``*#C$-"-XO"'O>@#0*#C!`"@X4``%+C`3!"X@0PC>7Z__\: +M`!"4Y50PG^4`$,;E`!"4Y0$0QN4`$)3E`A#&Y0`0E.4#$,;E`!"4Y000QN4` +M$)/E`@!1XP00DQ4`,)$5$C#'%P0``!H#`%7C!!"3E0`PD942,,.7````B@`P +M@>5\@+WH``````S!G^4!,*#A\$$MZ0!`H.,$8)SE!%"@X5`DY^<@C*#A4!CG +MYPA`AN4`<)SE!&"(!0(3CD4#!YQ5&S.>14,'G@5^%XQA%R^>24<3GDU+'YP);A>,> +M``#J#`#>10,'G:!"?Y0Q0 +MA>,24L3GHR"@X9)2QN>?0.80L?G``!1XP);A0,$(*`#$E;1 +M!P,`5^,&``":``!0XP)6A0,!2(0#DU+&!Q`PEN4?,<+G$#"&Y1`PG^4$()/E +M#$""Y00PD^4(4(/E\(&]Z`````#P3RWI;$*?Y2S03>(!@*#A*#"-X@*PH.$8 +M()3E#``CY0,0H.&\.=3A%E#4Y9(#`^`#`%#A"#"@(P0PH#,4,(WE_O__ZRP0 +ME.4<,)WE`0!3X0!`H#."```Z,`"4Y0,08>```%'A`4"@,WT``#HT()3E`1!@ +MX`(`4>$"0*`S>```.C@`E.4!(&+@``!2X0``X"-P```J<0``Z@0@DN4"+(+B +MA"2"X`@@C>4#``#J!""2Y0@0A.(!%(+@"!"-Y;0AG^6T$9_EH`"2Y0$`4.$% +M```*O!G2X0(`4>-=``":I""2Y0(`4^%:``":!`"@X0N@H.']]__K!#R@X0$X +M@^.%)*#A&#"-Y0B0H.$%,J#A$""-Y0PPC>4`8*#C6'&?Y3$``.H<`)WE`!"@ +MXP``AN#^___K'`"=Y0``AN`Q^?_K"3"@X0$`H.,`$*#C!2"@X0"@C>6U_/_K +M`#"7Y0$`5>,#`%.3!0``&@0`H.$!$*#C`""@XP4PH.$Y^O_K#0``Z@40H.$8 +M`)WE5___ZP00E^4`()?E"#"1Y0(`4N,D,(WE)3#=!28PW140,"/B4S+@YP`` +M4^/V__\:$""=Y0``6.,`(*`#!6"&X`*0B>`(()WE##"=Y0``6^-V8/_F`#"@ +M`P.@BN`0,*#C"#""Y10@G>6$,)_E`@!6X.-__\:A___Z@````!.04Y$$(#__]S$G^7P3RWI1-!- +MX@*`H.$6(-SE'#"-Y0@PW.44$(WE)`"-Y9(#`^`'`%/C#0``R@PPW.4``%/C +M!```"A@@G.6\.=SAD@,#X`,`4.$%```Z%!"=Y0@@H.$<,)WE)`"=Y?[__^L. +M`0#J)`"=Y8_Y_^M``!#C^___"F0TG^4*(-/E``!2XP(```J^-]/A`0!3X]`` +MYX4D$(WB_O__ZS0TG^4D$)WE+`"3Y0``4>$`8*`S^P`` +M.C#`D^4!`&#@#`!0X0%@H#/V```Z-""3Y0``;.`"`%#A`F"@,_$``#HX,)/E +M`"!BX`,`4N$``.`CZ0``*NH``.H$,)/E`CR#XH8T@^`8,(WE`P``Z@0PD^4( +M((;B`B2#X!@@C>6X,Y_EN".?Y:``D^4"`%#A!0``"KPIT^$"`%+CWP``FJ0P +MD^4#`%'AW```FHPSG^4((-/E`0!2XP<``)J\"=/A$,#3Y1@@D^6<``/@D@,# +MX`,`4>$"H*`C````*@&@H.,4$)WE!CR@X0!PH.,!.(/C$'"-Y2`PC>4,$(WE +M/$.?Y0L``.H6`-3E)#"=Y0,`@.`]^?_K0``0X_G__PH,()WE`7"'X@$PH.,0 +M,(WEBR2"X`P@C>4&`*#A(??_ZP$`6N,$```:)`"=Y6/X_^L,D)WE`%"@XV`` +M`.H6$-3E`0`'XB0@G>4L,)3ED2`@X`,`4.$`,*`S#@``.C`@E.4``&/@`@!0 +MX0$PH#,)```Z-#"4Y0``8N`#`%#A`C"@,P0``#HX()3E``!CX`(`4.'F__\J +M`S"@XP`@E.4"`%+C"%"#$@10E`4$()05`ER%`H-4A0`%5((0_O__ZQ#`G>4X +M((WB/#"-XC00C>(!D`SB`+"@X2;W_^L\()WE``!9XS@PG>4D`)3E`S""X#0@ +MG>4```O@DCDIX`"0B>"R-M01"0"@$2,TH!$(,(45!0``&KHUU.$C-*#A"#"% +MY0XPU.4``%/C"0"@$4;W_^L`$*#C!!"%Y000A>7_(`#B(#B@X00@A>4@!*#A +M!`"%Y00PA>6V___J``!8XW40[^80P*`3`,"@`P(@H.,!`*#CE8PLX`DPH.$` +MP(WEFOO_ZP00E.4`()3E"#"1Y0(`4N,P,(WE,3#=!3(PW140,"/B4S+@YP`` +M4^/V__\:(""=Y0(0H.,!FXGB!02"X0)0A>(X_O_K%K#4Y0L`5>'A__\Z``!8 +MXPN"B!`!`!?C`P``&@$PA^(*`%/A$2"@$Q```!H*,-3E',"=Y0``7.,``%,3 +M"@``"B0@G>45`-3EOC?4X0(`@.`8$)3E`3"#XKXWQ.'^___K``!1XQ4@H!,` +M```:$""@XP0`E.4`$)3E"#"0Y0(`4>,L,(WE+3#=!2XPW140,"/B4S+@YP`` +M4^/V__\:&!"=Y0@@@>4`()3E`@!2XP4``!H$$)3E`""1Y1,@P^4H,,WE*#"=Y0`P@N40()WE`3""XG,P[^8*`%/A +M3/__.F@PG^4!$*#C%,"=Y0``H.,5(-/E?!##Y5@0G^6P*+PC[WH`V"@XRPPG^4`()/E`@!2XQ3__QH.___J)`"?Y?[_ +M_^L0,)_E'`"?Y:00D^7^___K``"@X^___^H`````3D%.1!"`___#````\0`` +M`/!/+>D`D%/B3-!-X@E@H`$D`(WE&!"-Y1P@C>5PH)WE\@$`"OA'G^48$)WE +M'""=Y0Q0U.40$(WE``!5XPP@C>5Z```:2!"-X@@`(>7^___K0""=Y2PPE.4# +M`%+A#@``.C`0E.4"(&/@`0!2X0%0A3()```Z-#"4Y0(@8>`#`%+A`E"@,P0` +M`#HX$)3E`C!CX`$`4^'4`0`J`U"@XX"'G^4%`*#A,?;_ZS`PH.,`0*#C0`"= +MY;`XR.$(<*#AOC78X06LH.$$8*#A%S#(Y=7V_^L0@)WE30``ZD``G>4`$*#C +M``"$X/[__^L`,)?E`P!3XP4``!H`$*#C!0"@X0$@H.$!,*#C=OC_ZRP``.H* +M`*#A`1"@XY3]_^L,`)?H"!"3Y0(`4N,X$(WE.1#=!3H0W140$"'B41+@YP`` +M4>/V__\:`@!2X]"PDP4@L),5$C#7Y0``4^,\L(WE&```"CP@W>4%(`+B!0!2 +MXP4``!I`$)WE`&#@XZP&G^4!$(3@_O__ZPX``.K;L>/G`C!#X@,`6^$*``"Z +M0`"=Y0CV_^L`,)?E0!"=Y0(`4^-\!I_E`1"$X#RPG17;L>07"R"@X?[__^L, +MP)WE``"@XP@PH.$!(*#C`!"@X0%`A.(`P(WEL_K_ZQ@0G>44"+*`3`""@`P``7.,0,*`3`#"@`P*`B.`#$('@#!"-Y70@_^8(-I_E"0!2 +MX:W__SH`()/E`@!2XVH!`!IE`0#J2!"-X@$PP.,!L`#B`P"@X20P(>7^___K +M)""=Y2PPE.4#`%+A`%"@,V@!`#HP$)3E`B!CX`$`4N$!4*`S8P$`.C0PE.4" +M(&'@`P!2X0)0H#->`0`Z.!"4Y0(P8^`!`%/A50$`*E@!`.J$()/E)#"=Y0,` +M4N$7```*=#6?Y0`0H.,`()/E?1##Y0,`4N,'``":L"C3X3``4N,$```:!""3 +MY0@PDN4!!A/C-#"-Y?O__PH\-9_E,""@XR0`G>6P*,/A3/;_ZR0`G>4`$*#C +M_O__ZP4`H.&9]?_K%#6?Y0#`H.,H()/E"#6?Y0(`6N$D()TU`!"3Y0$@@C*^ +MQ\/A"R"",`D@@C`!(,(S`@!1XX0@@^5(``":*!"3Y0$`4N%%```J``!:XP(` +M``H!`%KAA*"#-0,``.H6,-/E`3!#X@,`$N$\```:J#2?Y1(@T^4``%+C`@`` +M&A0PT^4!`%/C-0``"HPTG^6\*=/A$`#3Y1@0D^60`@+@D0("X"00G>4"`%'A +M+```.H00D^4L()/E`@!1X0!`H#,/```Z,`"3Y0$08N```%'A`4"@,PH``#HT +M()/E`1!@X`(`4>$"0*`S!0``.C@PD^4!(&+@`P!2X01`H","```J`T"@XP4` +M5.$5```*#&2?Y00`H.%4]?_KA`"6Y0#V_^L`,);E`@!3XP0@EA4`,)(5'S#' +M%P0``!H#`%3C!""6E0`PDI4?,,.7````B@`P@N4%`*#A`1"@XR`0C>5"]?_K +M`0``Z@`@H.,@((WE`&"@XP4,H.$"$*#C%&"-Y0:`H.&X_/_KE$.?Y09PH.'" +M``#J"!"3Y0(`4N,P$(WE,1#=!3(0W140$"'B41+@YP``4>/V__\:`@!2X]`P +MDP4"```*`P!2XQ`PDP4@,),5`B"(XD0PC>4"(&O@"0!2X04``"H4,)WE`A"@ +MXP$`(^(%/*#A@`2#X9O\_^L2(-3E``!2XQX```H`$)3E1##=Y0(`4>-3,>"' +M"```B@0P`^)S,._F``!3XP$PH!,"```:``!;XT4PW073,.`'-$,)V%TS'DAP<``(H``%OC1#"=Y=,QXQ<#```:4Q7CY],Q +MX^7Y]/_K`,#@XX3`A.53``#JO"G4X1`0U.48,)3ED0("X),"`^`D +M()WE`P!2X0`PX#.$,(0U20``.@`PE.4"`%/C!@``&@,`5>,$()25`#"2E1\P +MPY4`((/E(""= +MY0``4N,U```:A#"4Y2@@E.4"`%/A,0``*@``6N,"```*`@!:X82@A#4#``#J +M%B#4Y0$@0N(#`!+A*```&H0@E.4L,)3E`P!2X0!0H#,.```Z,!"4Y0(@8^`! +M`%+A`5"@,PD``#HT,)3E`B!AX`,`4N$"4*`S!```.C@0E.4"4&/@`0!5X0-0 +MH#,$4*`C!0"@X:'T_^N$`)3E3?7_ZP`PE.4"`%/C!@``&@,`5>,$()25`#"2 +ME1\PPY4`((/E +M%""=Y0``H.,,P)WE$#"=Y8(0B^!V(._F`,"-Y0"PH.-Q$._F5/G_ZQ@0G>4< +M()WE``!1XQ#`G>6&-*`1`3"@`0``4N,,$)WE`F"@`10@G>4&8J`1!A"!X`$@ +M(N(,$(WE%""-Y0/`C.`0P(WE"0!8X7@PG^4,`)0X./__.@`@D^4'8*#A`@!2 +MXP4``!H#`%7C"0``B@0@D^4`,)+E'S##YP(``.H$()/E`#"2Y1\PQ^<`,(+E +M````Z@!@X.,&`*#A3-"-XO"/O>@#4*#C!0"@X5GT_^L4,)_EL!C3X;XET^$P +M`%'C%R##Y:'^_QJ<_O_J`````!D4T$WB`$"@X0.` +MH.$($(WE`:"@X0P@C>4"L*#A`'"@XQAAG^5```#J%E#6Y00`H.$+,-;E``!3 +MXX50H!%U4.\6!1"@X?[__^LX,)WE!`"@X0L@H.$`,(WE!5!AX`H0H.$(`%7A +M"%"@(750[^8%,*#AU/W_ZP$`<.,`D*#A%```&DS`EN4``%SC#```"@0`H.$* +M$*#A"R"@X04PH.$\_R_A`0!PXP!PH.$`<*`3%0``&@00H.&(`)_E_O__ZQ$` +M`.J``)_E!!"@X?[__^L)<*#A#```ZA(PUN4#,$/B`P!0X0@``#I,,);E``!3 +MXP$``!H$`*#A(_3_ZPD@H.%(`)_E!!"@X?[__^L(,)WE"(!EX`5`A.```%/C +M##"=Y86DBA!X@._F``!3XP6RBQ```%CCO/__&@<`H.$4T(WB\(^]Z`````!N +M`0``D`$``+$!``#P3RWI4$.?Y2S03>(`<*#A`I"@X10PC>7T.I3E)!"-Y0$` +M4^,(``"*`2"#XO0JA.4`(*#C#""-Y2`CG^5"BZ#C!&"@XY@C*.`2``#J0@N@ +MX_[__^L`@%#B!&"@$PP``!H08-3E0DR@XY0&`.#^___K`(!0X@8``!H$`*#A +M_O__ZP"`4.(`,.`#"#"-!:H```H!8*#C#("-Y;PRG^48()/E$!#3Y9(!"N`* +M`%GA``"@@P$`H),``%GC``"@`P``4.,`(.`#"""-!9$```J\"=/AD`$!X)(! +M`N`D$)WE`@!1X150TR67```Z"0"@X040H.'^___K!P"@X0%)B.()D&'@"A"@ +MX?[__^L$(*#A"#"@XP!PC>5YD/_F!P!AX``0H./^___KL##4X?(,4^,`(*`3 +M$""-%14``!JP,=3A`3"#XG,P_^:P,<3A``!3XP4``!JP(-3A#CQ#X@$@@N+_ +M(`+B`S""X;`PQ.$*$*#A!P"@X?[__^L!,*#C$#"-Y0H0H.&P`\3A)`"=Y?[_ +M_^NP!,3A`""@XR!`C>4(((WE"*"@X5```.H0,)WE`;"+X@#@X.,``%/C`""@ +M$P<`6^$!```J"0!6X0'@CC(($*#A!3"@X0#@C>7^___K!4"$X`@@G>5"C(CB +M!6"&X```4.,`(.`3"""-Y0<`6^$!*8CB"@"$X`8``#H`@*#C!V"@X0A`H.$* +M<*#A'+"=Y1B@G>4C``#J"0!4X=[__SKU___J%#"=Y20`G>4``%/C``"(X`,@ +MH!$#```:$""=Y0``4N,!*8L"(""=%0`PH.,+$*#A_O__ZP`P4.(!,*`3``!4 +MXP`PH!,``%/C`0``"@$`<.,D`(T5U#"?Y0%`A.($`*#A$!#3Y?[__^L``%'C +M`@``&B0`G>4D$(WB_O__ZT*\B^(%@(C@!@!4X0$``"H)`%CAVO__.I0%!.`D +M,)WE)!"-X@,PA.`)D&3@`P"@X01PA^!YD/_F)#"-Y?[__^L``%GC"```"@!` +MH.,4$L*#A!Z"@X09PH.$%8*#AM___Z@PPG>4``%/C`@`` +M"@,`H.'^___K`P``ZB@PG^7T*I/E`2!"XO0J@^4(`)WE+-"-XO"/O>@<()/E +M%E#3Y0(`6>%RD/^&8O__Z@````#X"@``\T$MZ0!@H.$""Z#C_O__ZP!`4.(` +M8.`#,@``"@`0H.-E+Z#CQ`"?Y0!0X./^___K!@"@X000H.$`(*#C`3"@XP!0 +MC>7^___K$8#4Y1`PU.42(-3E"(2#X1,PU.458-3E`HB(X8APG^4#C(CA%##4 +MY23@U.4&-(/A%,#7Y1P0U.4,(-?E``!0XP!@H`$%8*`18`"?Y0``6.$%8*`1 +M#`!>X05@H!$"`%'A!6"@$1(.4^,%8*`1"0``&@``5N,'```:!!"@X64OH..6 +M#H?B_O__ZP@`A^(8$(3B=""@X_[__^L$`*#A_O__ZP8`H.'\@;WH8`D````` +M``!$3D%.\$\MZ5A)G^4`4*#C7-!-X@!@H.$%$*#A=""@XP@`A.+T6H3E_O__ +MZP40H.$8(*#C?`"$XO[__^L%$*#A%""@XY0`A.+^___K_Q"@XR@@H..H`(3B +M_O__ZV4OH..6#H3B!1"@X?[__^L$8(3EH%"$Y0!0AN4$,)3E`""3Y?\`$N,2 +M```:_R"@XP`@@^4$,)3E`""3Y?\@`N+_`%+C"P``&@,@H.,`((3E`BJ@XP`@ +M@^4$,)3E'RQ"X@`0D^4""A'C8#&3%5,XXQ<`,(05`P``ZHPXG^40(*#C`A"@ +MXP`0@^5\.)_E&$"-XG18G^4`<*#C<+B?Y1>@H.,$$)/E!6"@X06`H.$`(('E +M,A"@XP`@D^43$,/E`@!2XTP(GP5,")\5_O__ZW<`[^8$$*#A_O__ZP+@U.4# +MD-3E!Q"@X03`U.4`(-3E`3#4Y20(G^4`X(WE`!*-Z?[__^L!(-3E`#"@XP,` +MV^=S$._F`@!0X0T``!H`")_E`S&`X```U.4@,)/EF`!0XRPPAN4"```:W@!2 +MXP(EH`,L((8%`3"@XP&@H.$0,,CE`@``Z@$P@^(8`%/CZO__&@%PA^(L();E +M*#"8Y00`5^,00(3B!&"&X@,P@N`H,(CETO__&H0GG^4`,*#C&,#=Y0`0X..( +M!Y_E%!#"Y0,0T.=S(._F`3"#X@P`4>$%```:6#>?Y0<`4N,4(,/E!""@`Q0@ +MPP4!``#J"`!3X_+__QH;(-WE`0"@XS`WG^6($!+B,A"@`P@`P^4-`,/E!0`` +M"H``4>,9$*`#`@``"@@`4>,,$($"/!"@$P0`6N,3$,/E!0``FO0VG^4%`%KC +M`1"@XPP0P^4`$*`##1##!=PVG^4,H-/E``!:XR@```H:$-WE`L"@XP``H.,# +M0`+B4>'AYQ'@P^4```#J?L#OY@$P@.($`%#AC."@X7,`[^;Y__^ZF.:?Y5(B +MX>>``*#C`#"@XQ;`SN4```#J@`"@X0'`@^("`%/A?##OYOK__[IL-I_E`Z`! +MXA0@T^4<`(/E`0!2XP$@@@('```*`2"@XU$2X><2$:#A<1#OY@@0P^4"`%'C +M!@``F@(@@N`((,/E`P``Z@$@H.,6(,/E'R""XAP@@^489I_E`""@XQ0PUN5, +M((;E`@!3XPA`UN4%```:&3#=Y=X`4^,"```:_O__ZP0VG^5,,(;EY#6?Y1$@ +MT^4"`%+C`P``&A0@T^4``%+CZ"6?!4P@@P7$-9_E%A#3Y4PPD^44,(WEE`$# +MX`<`4^,"``"*"`"@X_[__^L`0*#AG&6?Y73`[^80P(WE%G#6Y1PPEN4'$*#A +MEPP"X`,`H.&3!`/@%2#&Y1@PAN7^___K!Q"@X2``AN4L`);E_O__ZP`0X..\ +M&<;A,#J@X1@`C>(D,(;E_O__ZR@PEN4``%/C#```&A0PUN7_`%/C!@``"@$Q +MH.,6$-;E`P"@X2PPAN7^___K,`J@X20`AN40-9_E`2"@XQ`@P^4$99_E`'"@ +MXQ:.AN(VGH;B`#"6Y0(`4^,.`*`#&`"@$_[__^L<`);E`""@X_@4G^4$,*#C +M`,#@XY`'`.``P(WE_O__ZP``4.,.```*`#"6Y0(`4^,(`*`#$`"@$_[__^L< +M`);E`""@X[P4G^4$,*#C`,#@XY`'`.``P(WE_O__ZP``4..H```:`0#8Y0`P +MV.4"$-CE`R#8Y0`T@^&,!)_E`3B#X0(\@^$``%/AG@``&@L@V>52&P3C"C#9 +MY7"TG^4"-(/A`0!3X9<``!KM,=GE$B#6Y0,`4N$!```*``!3XY$``!H@-)_E +MZ1';Y0P@T^43$,/E``!2XP4```KK$=OE[`';Y>HAV^46`,/E`22"X1P@@^7P +M8Y_E$,"=Y1:`UN4<();EF`P#X)($!.!S,._F!`"@X0,0H.$5,,;E&$"&Y?[_ +M_^L($*#A(`"&Y2P`EN7^___K8$#;Y0/@V^4%$-OE88#;Y0+`V^4$(-OE`3#; +MY0B$E.$.Q(SA`$#;Y0$D@N&,Q:#A`T2$X8(EH.&4P(;EF""&Y3`*H.$D`(;E +M&@``"O[__^L,,-;E``!3XPT```IA(-OE8##;Y18`UN4")(/A`S#@XR(1H.$! +M8(;@DR$BX-`PUN60(R/@4"-(/AD#<@X/[__^L!`'#C)P``&O@RG^41(-/E`@!2XPX``!H4(-/E``!2 +MXPL``!H!$*#C`RN"X@@0P^4G$('B&""#Y1P@@^6_+D+B$Q##Y9@0@>(5(,/E +M(!"#Y18@P^6L,I_E%"#3Y00`4N,!`%(3`@``"A8PT^4/`%/C`@``FHPRG^4! +M(*#C#B##Y8`RG^44(-/E`0!2XP4``!H6$-/E"`!1XP(``(H9$-WET0!1XP\@ +MPQ58,I_E[2';Y9C`D^64`)/E*!"3Y0``C.`2(,/E`0!0X0"0X",`D*`S``!2 +MXP4``!H4(-/E`0!2X_$`H`.V!L,!1"*?!;(FPP$0,I_E$R#3Y3P`4N,\(*"# +M$R##A?PQG^43(-/E)P!2XP@``(H4(-/E`@!2XR8@@@(3(,,%`P``Z@%PA^(R +M`%?C-?__&@"0X./(,9_E&'"-XL"!G^4`H*#C`#"3Y0A@H.$"`%/CM`&?!;0! +MGQ7^___K+#"8Y0``4^,G```*`N#7Y0$0BN($P-?E`[#7Y0`@U^4!,-?EK`&? +MY0#@C>4`&(WI_O__ZRP0F.6<`9_EH16@X?[__^L<$);ED`&?Y?[__^L6$-;E +MB`&?Y?[__^L5$-;E@`&?Y?[__^L8$);E>`&?Y?[__^MT`9_E_O__ZQ$0UN5L +M`9_E_O__ZP@0UN5D`9_E_O__ZPD0UN5<`9_E_O__ZU@!G^43$-;E_O__ZP&@ +MBN($@(CB!`!:XQ!PA^+/__\:X#"?Y0@@T^4!`%+C`P``F@\PT^4``%/C`4"$ +M`J1`H`'`8)_E%!"=Y1"`AN(8,);E$'#6Y90`EN63!`+@`0!`XI,'!^!,$(;E +M`3!"XKQ)QN&D,(;E!Q"@X0<`@.#^___KF""6Y0<0H.$!($+BEP`#X`<`@N"4 +M,(;E_O__ZY<`!^`2`-;EF'"&Y?[__^L0(-;E&!"6Y0`PH.,H,(;E`T"@X9$" +M!N`L,)7E!A"@X0``4^("```*_O__ZY8``.`L`(7E+#"5Y010A>((`%7A`T"$ +MX//__QH,,)_E"0"@X2A`@^5`(``)8"``"B`@``N@(``.@"```7`P``\$\MZ5Q#G^4LT$WB`:"@X0*0 +MH.$`8*#A##"-Y1$PU.4!`%/CRP``FA00U.4``%'CR```&O[__^L`()3E`P!2 +MXP0``)H$$)3E"#"1Y0$&$^,D,(WE^___"@@SG^4L`)/E``!6X0!0H#,.```Z +M,,"3Y08`8.`,`%#A`5"@,PD``#HT$)/E``!LX`$`4.$"4*`S!```.C@PD^4` +M4&'@`P!5X0-0H#,$4*`C`@!2X[0RG^4&```:!$"3Y00`5>,&/*`#A32@$0), +MA.(#0(3@`@``Z@0PD^4(0(7B!$2#X`4`H.$X\/_K`#"@XZ+`H.,H`*#C$!"- +MX@@`4^,(P(3E`R"@$P`@H`,$((3E.RZ#$A(@H`,!(((2_R`"$@0@A.4<`(WE +M'""=Y0``4N,!X$+B'."-Y?K__QH`X)3E`^#!YP$P@^()`%/CZO__&A@RG^4` +M$)/E`@!1XP00DQ4`,)$5$C#'%P0``!H#`%7C`P``B@00D^4`,)'E$C##YP`P +M@>7D<9_E`("@XP4`H.$.\/_KV"&?Y0D0H.,`,*#CD2@AX`@`4^.A(*#C"""$ +MY0,@H!,`(*`#!""$Y3LN@Q(!(((2$B"@`_\@`A($((3E$""-X@,@TN=R`*_F +MT"#1X0`@8N``((3E*""@XQP@C>4<()WE``!2XP$`0N(<`(WE^O__&@$P@^(! +M$('B"0!3X^/__QH`,)?E`@!3XP8``!H#`%7C!!"7E0`PD942,,.7(#"-E0`P +M@94%``#J!#"7Y0`0D^4@$(WE("#-Y2`@G>4`((/E"A"@X0D@H.$,,)WE!@"@ +MX0#`X.,`P(WE>_G_ZP`0H.,`L*#A!@"@X?[__^L!`'OC`@``&@&`B.(3`%CC +MO?__&@4`H.',[__K`#"@XZ'`H.,0`(WB*!"@XP@`4^,(P(3E`R"@$P`@H`,$ +M((3E.RZ#$A(@H`,!(((2_R`"$@0@A.73()#A`""$Y1P0C>4<()WE``!2XP%P +M0N(<<(WE^O__&@$P@^()`%/CZO__&F@PG^4`$)/E`@!1XP00DQ4`,)$5$C#' +M%P0``!H#`%7C!!"3E0`PD942,,.7````B@`P@>4!`'OC"0``&@8`H.$*$*#A +M"2"@X0PPG>4`P*#C`,"-Y4'Y_^L`L*#A````Z@"PX.,+`*#A+-"-XO"/O>@` +M````@````/!/+>DLT$WB`("@X1`0C>4`$*#C&#"-Y10@C>7^___KN#*?Y2P0 +MD^4!`%CA`$"@,PX``#HP`)/E"!!AX```4>$!0*`S"0``.C0@D^4!$&#@`@!1 +MX0)`H#,$```Z.#"3Y0%`8N`#`%3A`T"@,P1`H"-H,I_E`""3Y0(`4N,&```: +M!%"3Y00`5.,&/*`#A#2@$0)(#4(7@`@``Z@0PD^4(4(3B!52#X`$PH.,$ +M<*#A##"-Y2@RG^4$,8/@'#"-Y1A"G^4`8*#C!P"@X1RPG>5@[__K-C"@XP@" +MG^4&$*#A"#"%Y:R@H./^___K^#&?Y0:1@^`$H(7ET"#9X=`PV^'H`9_E`S"" +MX``PA>70,-OAT!#9X0,0@>!Q$._F_O__ZPHPH.,@,(WE(#"=Y0``4^,!($/B +M(""-Y?K__QH!H(KB`;"+XK``6N,!D(GBZ/__&IP!G^4(,(WE_O__ZQ8@H.,( +M((7E`""4Y0@PG>4"`%+C!@``&@,`5^,$$)25`""1E1,@PY4D,,WE)#"=Y0`P@N40$)WE"`"@X10@G>4`P.#C&#"= +MY0#`C>7(^/_K`!"@XP"@H.$(`*#A_O__ZP$`>N,#```*!0!6XP=`H.$6``": +M"P``Z@%@AN(*`%;CL___&O@`G^4,$)WE_O__ZPPPG>4``%/C`3!#$@PPC16I +M__\:!T"@X;PPG^42,-/E#0!3XP0@H(,"(*"3`S!BX`,`6N$!```Z"`"@X1CO +M_^L$`*#A`N__ZY`0G^6L,*#C"@"@XP01@>`V(*#C"""%Y00PA>70(-'A`""% +MY2``C>4@()WE``!2XP'`0N(@P(WE^O__&@$P@^(!$('BL`!3X_+__QI`,)_E +M%A"@XP@0A>4`$)/E`@!1XP00DQ4`,)$5$C#'%P0``!H#`%3C!!"3E0`PD942 +M,,.7````B@`P@>4*`*#A+-"-XO"/O>@`````4`$``"P#```L`0``?0```(4` +M``!,`P``[)BMP2P'((EU=GAY.CP```$````" +M````!`````0````(````!`````0````(````$````"````!`````"````!`` +M```@````0````(```````0``0````(```````0````(````!`````0````+W +M^/?W]_CY^0KW^??W^/G[^PKX^OCX^?K\_`KY^_GY^OO]_0KZ_/KZ^_S^_@K[ +M_?O[_/W__PK\_OS\_?X```K\__W\_O\!`0K\`/[\_P`"`@K_`?__``$#`PH` +M!````00$!`H!`P`!`@,%!0H"!``"`P0&!@H"!0$"!`4'!PH"!@("!08("`H# +M!P,#!@<)"0H$"`0$!P@,"@H%"04%"`D-"PH&"@8&"0H.#`H````"```#!00` +M!@@&``@+"``*#@H`_OOZ`/SV]0#Y\N\`]N[J``#IY`>Q`8&PL%^$``````>Q +M`8&PL%^$``````````"PL+"`$````+"PL(`@````L+"P@&0```"PL+"`D``` +M`+"PL(`,`0``L+"P@"0!``"PL+"`=`$``+"PJ(#P`0``L+"L@,0"``"PL*J` +M4`,``+"PL(#<`P``K`^Q@#P&``"L#[&`[`<``+"K!(!L"0``J`.Q@$P*``"K +M![&`F`H``+"PKX#<"P``L+"P@,0,``"PL*B`!`X```````#T#@``L+"P@/@. +M``"PL+"`_`X``+"PK(!X#P``L%^$@/`/``"J/P6`0!```+"PL(!T$```L+"P +M@'P0``"PL+"`A!```+"PL("($```L+"P@)@0``"PL+"`J!```+"PK(!0$0`` +ML+"H@*P1``"PL*B`"!(``*\'L8`$$P``L+"L@%P4``"PL+"`8!0``+"PL(!D +M%```L+"N@/05``"PL*J`0!8``+"PJ(!4%@``L+"H@&@6``"PL*B`A!8``+"P +MJH#D%P``L+"P@.@7``"PL+"`\!<```P````$&@``L*\$@*P;``"N#[&`)!X` +M`*H#L8`@'P``L+"L@#@@``"PKPJ`O"(``+"O$("T)P``L*\2@.@O``"PKP2` +M/#$``+"O"H"@-```K`.Q@)PU``"PKQ:`7#\``+"O"H#,0@``L*\*@'Q.`P15 +M!0D'+2Q[.!<-%Q%#4E5?05!,3%]#3TXZ("5L>`H`07)M4&QL.B`E;&0@34AZ +M"@!#4E5?0TQ+4T5,,%]#3TXZ("5L>`H`06AB0VQK.B`E;&0@34AZ"@!!2$(@ +M/25L9"!-2'H`/#4^2'EN:7A'971296%D4F5T"``/#4^"@!!8V-ECH@)6QD +M($UH>@H`1FQA`H`9T9L87-H26YF;RYS>7-);F9O +M+G-Y2!E`H`1FQA`H`/#4^97)R +M;W(@"P@97)R;W(@8FET/25L9`H`1FQA"`E>"`E>"`E>"`E +M>`H`/#4^"0D@0V%P.@D))61-0@H`/#4^"0E";&]C:U)A=R`Z"25D('-E8W1O +M<@H`/#4^"0E086=E4F%W(#H))60@2`E;&0Z(```1T-#.B`H1TY5*2`T +M+C0N,`!!*@```&%E86)I``$@````!36UT86(`+G-T'1A8@`N&ED>``N`\```````````$`"0```/`/```````````!``P````\$``` +M`````````0`)````0!````````````$`#````'`0```````````!``D```!T +M$````````````0`)````?!````````````$`"0```(00```````````!``D` +M``"($````````````0`,````E!````````````$`"0```)@0```````````! +M``P```"D$````````````0`)````J!````````````$`#````$`1```````` +M```!``D```!0$0```````````0`,````H!$```````````$`"0```*P1```` +M```````!``P```#\$0```````````0`)````"!(```````````$`#````/`2 +M```````````!``D````$$P```````````0`,````3!0```````````$`"0`` +M`%P4```````````!``D```!@%````````````0"H````9!0``)`!```"``$` +M"0```&04```````````!``P```#L%0```````````0`)````]!4````````` +M``$`#````#P6```````````!``D```!`%@```````````0`)````5!8````` +M``````$`"0```&@6```````````!``D```"$%@```````````0`,````V!<` +M``````````$`"0```.07```````````!``D```#H%P```````````0`)```` +M\!<```````````$`#````/P9```````````!``D````$&@```````````0`, +M````I!L```````````$`"0```*P;```````````!``P````<'@`````````` +M`0`)````)!X```````````$`#````!P?```````````!`+4````@'P``&`$` +M``(``0`)````(!\```````````$`#````#0@```````````!``D````X(``` +M`````````0`,````L"(```````````$`"0```+PB```````````!``P```"@ +M)P```````````0#,````M"<``#0(```"``$`"0```+0G```````````!``P` +M``#8+P```````````0`)````Z"\```````````$`#````"PQ```````````! +M``D````\,0```````````0`,````F#0```````````$`"0```*`T```````` +M```!``P```"0-0```````````0`)````G#4```````````$`#``````_```` +M```````!``D```!`\``'@````2``$`%`(``/`/``!0````$@`!`"@"``!`$``` +M-````!(``0`T`@``=!````@````2``$`00(``'P0```(````$@`!`%`"``"$ +M$```!````!(``0!@`@`````````````0````=0(``(@0```0````$@`!`)(" +M`````````````!````":`@``F!```!`````2``$`I@(``*@0``"H````$@`! +M`+`"`````````````!````"W`@``4!$``%P````2``$`T`(``*P1``!<```` +M$@`!`-@"```($@``_````!(``0#Q`@``!!,``%@!```2``$```,``%P4```$ +M````$@`!``L#`````````````!`````2`P``8!0```0````2``$`'0,````` +M````````$````"0#``#T%0``3````!(``0`V`P``0!8``!0````2``$`2`,` +M`%06```4````$@`!`%@#``!H%@``'````!(``0!C`P`````````````0```` +M:@,``(06``!@`0``$@`!`'@#``#D%P``!````!(``0"!`P`````````````0 +M````AP,``.@7```(````$@`!`)(#`````````````!````"<`P``\!<``!0" +M```2``$`J@,`````````````$````+X#`````````````!````#-`P`````` +M```````0````V@,```0:``"H`0``$@`!`/,#``"L&P``>`(``!(``0`#!``` +M)!X``/P````2``$`#P0``#@@``"$`@``$@`!`"($``"\(@``^`0``!(``0`T +M!```Z"\``%0!```2``$`1@0`````````````$````%8$```\,0``9`,``!(` +M`0!D!``````````````0````<@0``*`T``#\````$@`!`(($``"<-0``P`D` +M`!(``0",!```S$(``/P"```2``$`G00``%P_``!P`P``$@`!`+`$```````` +M"````!$``P#!!```"````!@````1``,`S`0``"````!@````$0`#`-<$```L +M`0``*````!$``P#A!```@````*L````1``,`Z@0``-````"`````$0`$`/<$ +M````````T````!$`!``"!0``8`D``)0!```1``0`#P4``&`!````"```$0`$ +M`!H%``#X"@```!`"`!$`!``K!0``]`H```0````1``0`004``%`!```0```` +M$0`$``!F;&%S:"YC`"1A`"1D`$9L87-H0W,`1FQA0!&;&%S:%AF97)3=&%R="YC;&]N92XP`$9L87-H4F5A9%!A9V4`0RXS +M-#@N,34U,#``1FQA5-E='5P`$Y!3D1?4D,T7T-I<&AE<@!'971) +M9&)L;V-K1&%T84YO4F,T`$9L87-H0W-);FET`$9L87-H0W-);TUU>`!&;&%S +M:$1E0W-);TUU>`!&=&Q77-$871A`$=E=$-H:7!396-T;W));F9O`$=E=%-.4V5C=&]R +M26YF;P!F=&Q?;65M5!R +M;V<`1G1L,D9L87-H4')O9P!296QO861&;&%S:$EN9F\`1FQA5!R;V="=69);F1E>`!D +M969A=6QT5F%L=64````,`````@0``!P````"!```7`````($``",`````@0` +M``@!```"!```(`$```($``!P`0```@0``*0!````@` +M`!R,```<"0``'(P``&@)```"!```2`H```($``#8"P```@0``*P,```"!``` +M``X```($``#P#@```@0``&0/```_R^1``!1XT@@DQ6`,*`1@`"@X;,0 MDA$!$($2LQ""$0@PG^5(,)/EL`"3X1[_+^$`````3#"?Y;(CT^$``%+A'O\O MD4@@D^6``*#A_\\/XPP`4>$`$*`#L!""X;H!T^$@()/E`0!0X;H1PS$"(('@ @@ -32,17 +32,17 @@ M``7@`""@X[@@P^'8,`KC`R"$YPA0A.W__SH#`%#AU#`*(P`0X",$()\E`Q"")_R!O>@`````V#"?Y?!/+>G4 -M<)_EN%#3X47?3>*TA-/ALB33X4AP@^68!0;@NA#3X08`4N$H``"Z`0!2X28` +M<)_EN%#3X87?3>*TA-/ALB33X4AP@^68!0;@NA#3X08`4N$H``"Z`0!2X28` M`(JPE-/A`F!FX`!`H..%I*#A=F#_YA"PC>*9`0G@=<#OYA,``.H`X*#C#,"- MY0#@C>7^___KL"'=X5H5"N,%8(;@`3"$X@$`4N$,P)WE=F#_Y@(``!JP(MWA M!`!2X0,```H$$*#A1`"?Y?[__^L'``#J@`````X"`#```` +M,*#A"G"'X.3__SH(`%3A``"@`P````H``.#CA=^-XO"/O>@`````X"`#```` M`````*#C_O__Z@``G^7^___J3D%.1'PPG^4`(*#C\$5!;(;B +MXP)`H.$#H*#A`G"@X0"`X.,!((/G`0F&XO\0H.,"+*#C#$!%Y01@!>5";(;B M"W!%Y1!P!>7^___K!#"*X`%`A.(G.X/B(`!4X^XP@^(44(7B`(##Y>[__QH, M()_E#CT)XP`0X.,#$,+G\(>]Z``````HG0``X"`$```PH.,T()_E-`"?Y0,0 MH.'#P*#A`3R#X@(*4^,4$,+E#,&`X!C`@N4<((+B]___&@P`G^7_$*#C`BF@ -MX_[__^J`````X$`,`'!`+>ET0)_E`!"@XS@@H.,4`(3B`%#@X_[__^M@,)_E +MX_[__^J`````X&`,`'!`+>ET0)_E`!"@XS@@H.,4`(3B`%#@X_[__^M@,)_E M0."@X[[AQ.&^X-3A`,"@XPP0H.$"*:#C`P"@X;K!Q.&RX\3A`<",XD@PA.4D MP(3EM,'$X;A1Q.'^___KN!#4X;X`U.$%,('@LE3$X;!4Q.$@!(/@_O__Z[0$ MQ.%P@+WH`````.`@`P!P0"WI+$"?Y=10"N,,$`CC!0"$X/[__^O8(`KC`#"@ @@ -53,188 +53,188 @@ M@^*S4(3A`3N@XW`@_^:^(,3AE`"?Y:(BH.$!"U+C`2N@(X``4N.`(*`SLR"$ MX8!`A.*"(*#A_O__ZP4PH.$!((7B$%#$Y1$PQ.4<0(3B/X__\: M9O__Z_[__^L`(*#C1#"?Y0(`H.%`$)_E`<""X@P@0^4$$`/E`AJ!XGP@_^8+ M`$/E$`!2XQ```^44,(/B]?__&O[__^MP0+WH>/__Z@``````````"@0``*B? -M``#@(`$`\$\MZ1!1G^44T$WB`'"@X0)@H.&ZD-7A`!"-Y0D0H.$$,(WE_O__ -MZW"`_^:9"`/@`P!7X0!`H!,O```:(#"5Y06@H.$`0*#C#+"-X@$P@^(@,(7E +M``#@(`$`\$\MZ0Q1G^44T$WB`'"@X0)@H.&ZD-7A`!"-Y0D0H.$$,(WE_O__ +MZW"`_^:9"`/@`P!7X0!`H!,N```:(#"5Y06@H.$`0*#C#+"-X@$P@^(@,(7E MLB/:X8@PH.$`4*#C"`!2X04``)I(()KELQ"2X0$0@>*S$(+A2"":Y;-0DN$+ -M$*#A!P"@X?[__^L``%#C#0``"@<0H.&``)_E_O__ZPPPG>4)$*#A`P!7X0,` -MH.$#0*#A`W"@X0!`X`,3```*_O__ZW"`_^;A___J2#"?Y;HAT^$%`%+ANE'# -M,0``5N,%```*L##6X0\*4^,"```*\@Q3X[!7QN&PA,8!!P"@X0`0G>4&(*#A -M!#"=Y?[__^L$`*#A%-"-XO"/O>@`````'````/!/+>D4=)_EXCP(X^!L".,` -MP*#C2=]-XK/`A^$D/0GC`!"@XP@@H.,#4)?G`CN@X^P#G^6V,(?A`##@X[I` -MU^$%@*#A'#&-Y1@QC>7^___KMB"7X?\0H./(`Y_E`6"@X010H.&"(*#A_O__ -MZ[R@U^&:!`G@(@``Z@#`H.,`P(WE_O__ZP$PA^(``%#C"@``&K@AW>$!,(;B -M#PI2XQ,``!H``%3C$@Z-XG-@[P9V,*_F`S&`X`BP`^4"``#J$#0(3@!0!4X0FPA.`($*#A"P"@X1@@C>(!,*#CX?__.G8P -MK^8%D(G@``!3XP<``,H!H(KB%".?Y;PPTN$R,(/B`P!:X0!PH#,'0*`Q[/__ -M.G9@K^8``Y_E!A"@X05`H.'^___K`0!VXPA0H.$#```:Z`*?Y?[__^L&`*#A -ML0``ZABAG>4$$*#A"@"@X?[__^L<89WE!@"@X0%PH.$$$*#A_O__ZP$`5^$! -M@*#A!0``"@$`=N,#```*`0!ZXP(```H!`%?A````F@I@H.$%$*#A&""-X@@P -MH.,&`*#A`,#@XP#`C>7^___K=!*?Y1+.C>*XY-WAN*7=X;$0G.&XEMWAN+?= -MX;C(W>&X(MWAN#/=X5`"G^4`X(WE!*"-Y0B0C>4,L(WE$,"-Y?[__^L(`%?A -M)```"@00H.$&`*#A_O__Z[@5W>&X)MWAE`$#X`$`4.$<,8T%&#&-%90"`@#L -M,9_EE`("$!@AC04<(8T5O"#3X0(`4>$"```ZN#;=X0(`4^$!```JX`&?Y5@` -M`.K<`9_E&&"-XO[__^L%$*#A!B"@X0`PH.,8`9WE_O__ZP8@H.$<`9WE!1"@ -MX0`PH./^___K``"@X_[__^N`,9_EZAP(X[C'W>'B#`CCN"/=X?_G`..QP(/A -M`A"!XKC(W>&R(&P((/AX"P(X[00P^$` -M$*#CLB"3X04``.JW8)7A#`!6X0D```JP8)/A`6"&XK!@@^$.`%+A@7"@X0)@ -MH)$":Z"#!@!1X0$0@>+R__\Z@B"@X040H.$""U+C`BN@H_``G^7^___K&&&= -MY1QQG>4$$*#AU%"?Y0<`5N$&`*`Q!P"@(?[__^OF/`CC!!"@X;,`A>$'`%;A -M!@"@(0<`H#'^___KZ#P(XP00H.&S`(7A!@"@X?[__^NT,-7A(R2@X00`4N/D -M+`CCLA"%X0,0H!&<`)\50BZ@$P0``!JP$=7AOB#5X0(`4>$"```ZA`"?Y?[_ -M_^L2``#JH@!1X00``"IP`)_E_O__Z[XPU>$C,4/@L#'%X31`G^7B7`CC6`"? -MY;40E.'^___KOB#4X;4PE.$B`E/A``"@DP(``)H\`)_E_O__ZP``X.-)WXWB -M\(^]Z`````#FC```[HP``#\```!9````^/[__VT```"?````3D%.1,X```#Y -M````,P$``$L!``#P3RWI?*&?Y>H\".,`@*#AH]]-X@&0H.&S4)KA`K"@X;I@ -MVN&6!07@!0"@X2C]_^M4,9_E`P!8X7!PO^8,```:`BR-X@!`H./S/*#C!P"@ -MX;@PPN$&$*#A"$"-Y0Q`C>400(WE_O__ZP0PH.&"+XWB#0``ZA1!G^4$`%CA -M#@``&@(LC>+S/*#C!P"@X080H.&X,,+A"("-Y0R0C>40L(WE_O__ZX(OC>(` -M,*#C!0"!X`@0C>+^___K,```ZM`PG^4`(%?B`2"@$P,`6.$`(*`3``!2XP*` -MH.$H```*N`#:X0B0C>*"KXWB`3"@XP4`8.`)$*#A"B"@X0<`@.``P.#C`,"- -MY?[__^L(,)WE!`!3X1H``!H"/(WBN(#3X?,,6.,6```:`$"@XV@`G^7^___K -M!#"@X08@H.$0$)WE#`"=Y?[__^L"+(WB!P"@X080H.&X@,+A"$"-Y0Q`C>40 -M0(WE_O__ZPH@H.$$,*#A!0"!X`D0H.'^___K!`"@X?[__^NCWXWB\(^]Z``` -M`````%-5$1%352(B4U5.04Y$:#&?Y>(<"./P12WI`""@X;$`D^$"$$'BA-!- -MXKI0T^&Q$)/A``!1X0`0H(,#``"*3```ZK#`W.$"`%SA20``"H'`@^```%'A -M(\N,X@$0@>+NP(SB%$&?Y?7__SI&#(#BXCP(XW0`@.+FK`CCLQ"4X>B,"..` -MP(3@ZNP(X^1\"./L`)_EMB#,X>PL"..RP=3A#6"@X;(@E.&^X)3AL,+-X;`G -MS>$!(('BLR"$X;0PU.&ZP)3AL.;-X;`QS>$`,*#CL#/-X;@PE.&PQ,WAL#7- -MX0\ZH..P,,WA_O__Z[?`E.&Z`)3A!0!@`````3D%.1.Z,```00"WI+`"? -MY201".,`(*#C_O__ZR`PG^4``%#C$`2#Y0`PH!,T,(`5/#"`%0PPGQ4X,(`5 -M$("]Z&T!``#0O`P`````````4N/P02WI`W"@X0!0H.$!,*#C`$"@$0`P@>5; -M```:?!&?Y7PAG^7^___K>$&?Y0!@A>!T`9_E_O__Z[@@U.%L$9_E!@"@X?[_ -M_^NZ(-3A8!&?Y0!@AN`&`*#A_O__Z[`AU.%0$9_E`&"&X`8`H.'^___KLB'4 -MX4`1G^4`8(;@!@"@X?[__^L(-`#C,!&?Y;,@E.$`8(;@!@"@X?[__^L&-`#C -M'!&?Y;,@E.$`8(;@!@"@X?[__^L@()3E"!&?Y0!@AN`&`*#A_O__ZRP@E.7X -M$)_E`&"&X`8`H.'^___KNB'4X>@0G^4`8(;@!@"@X?[__^NX(=3AV!"?Y0!@ -MAN`&`*#A_O__Z[XAU.'($)_E`&"&X`8`H.'^___KO"'4X;@0G^4`8(;@!@"@ -MX?[__^NT$]3A`&"&X"``E.7^___KG!"?Y0`@H.$&`*#A_O__ZUP@E.6,$)_E -M`&"&X`8`H.'^___K.""4Y7P0G^4`8(;@!@"@X?[__^L\()3E;!"?Y0!`AN`$ -M`*#A_O__ZP!`A.`$0&7@!P!4X00`H+$'`*"A\(&]Z'8!`````````````'H! -M``"0`0``H@$``+,!``#(`0``X`$``/,!```&`@``'@(``#,"``!-`@``9P(` -M`(8"``"E`@``OP(``,\"``#D`@``^$\MZ0@QG^4&)`#CLI"3X0``6>,\```* -M"!0`XR0@D^6Q<)/A`@!2XPF09^!Y*!0(3@LI#4X0L``.K^___K!0"@X0&@BN)ZH/_F@4^!X@@0H.'^___KA$"+ -MX($?@>*!$(O@LA#1X;(0Q.$&`%KA`5!%X@@0H.$!`(7B[O__.@``5^-$0)_E -M"#0``P)4`.,X()\%M0"4X;,0D@$!`(#B`1!!`K,0@@$&-`#C`1N@X[,@E.&Q -M$)3A`2!"XK,@A.'^___KM1"$X0D`H.'XC[WH`````&0QG^7P3RWI`$"@X;*S -MT^$4T$WB"P!0X0"`H"-((),U@#"@,;.`DC$&)`#C.#&?Y;)PD^$!*Z#CLJ"3 -MX0H`5^%'```*`B""XD@`D^4`8*#C`\"@X;(@D^$!D*#C#`"-Y090H.$(((WE -M$0``Z@3`C>7^___K!,"=Y0$PB>*!'X'B@1",X+(@T>$+`%+A@A"@X0,``"H, -M`)WEL1"0X0@`4>$```"*"5"@X0(`5.%SD/_F*P``"G8P_^8(()WE!P!3X0H0 -MH.$"`(;@`6"&XN;__SH(``#J_O__ZP%0A>)U4/_F@1^!XH$0B>"R,-'ALD#! -MX0-`H.$```#J;)"?Y0@PG>4'`%7A"A"@X5Q@G^4#`(7@[___.@14`.,!.Z#C -M!B0`XP%PA^*U`);ALQ"6X8$_@.*R<(;A`0"`XH,PAN"R0,/A_O__Z[XQUN$$ -M,$/B`P!8X0@T`*.S():AM1"&X0$@@J*S((:A%-"-XO"/O>@`````\4\MZ1Q! -MG^4(-`#C`2N@X[-0E.$",$/BLG"4X;.@E.$$,$/B!Q"@X;,PE.$*H&7@>J#S -MY@H`H.'^___K``!5XX$?@>*!$(3@LF#1X3(```JR,]3AS("?Y08`4^&&,*"! -M`#"@DT@@E(6S,)*!OB'8X0,`4N$!L$6"`%"@@PP``(HE``#J_O__ZP$`B>(! -M4(7B=5#_YH%/@>('$*#A_O__ZX1`B."!'X'B@1"(X+(0T>&R$,3A"P!5X0J0 -MA>`'$*#A"0"@X5Q`G^7M__^Z!%0`XP$;H.,(-`#C!B0`X[7`E.&Q`)3ALN"4 -MX0`0H.$``(S@L\"4X0'@3N(!`$#BLN"$X0$@3.*S((3A_O__ZP8`H.&U$(3A -M!-"-XO"/O>@$T(WB\$^]Z!/__^H`````B#"?Y084`.,00"WIM"'3X;$0D^$! -M`%+C""0`X[(@D^$8```:`2!BX'(@_^8/`%+C#P``B@`@T^4!`%+C#```&B0P -MD^4"`%/C`0``&J#__^L```#J_/[_ZS`PG^6^(=/ANA'3X0(`4>$!(*`CMB'# -M(0```.KT_O_K$#"?Y0$@H.,D((/E$("]Z!!`O>B0___J`````/!/+>GH0)_E -M_S\/XXS03>*P)-3A2'"4Y0,`4N&Z(-3ANX;2$U.$$((WE`P``&LW__^L` -M,*#CLC3$X;`$Q.&L0)_E!,"=Y;(TU.&8-B/@#`!3X04``-JP!-3A&___Z\'_ -M_^L`(*#CLB3$X;`$Q.%\,)_EAJ2@X03`G>4`4*#C`T"@X6R0G^6P--/A"+"- -MXIP#`^`$,(WE$0``ZK(4U.%4`)_EN%'-X0%0A>*XD,WA_O__Z[($U.$'$*#A -M!,"=Y0`PH.,+(*#A"G"'X```C.!U4/_F_O__Z[(TU.$#,(;@LC3$X0@`5>'K -M__\ZC-"-XO"/O>@`````6J7___8"``#P3RWIH$*?Y:303>*<`I_EL#'4X7\_ -M@^(#,(/BHS2@X10PC>7^___KU"P`XP`PH.,$P*#A`W"@X;(`E.$!$*#C`P`` -MZ@(AC.#,+)+E$202X'5P_Q9S(/_F'T`#X@``4N$!4(?B`3"#XJ(BH.'T__\Z -M``!7XXH```HL0I_EV%P`X[@0U.&U()3ANC#4X9$G(N`#`%+A"```NM9L`..V -MD)3A@QG^76+`#C`&"@XP&@ -MH.,#4*#AG&"-Y;(@D^'8C`#CNC#3X9A@C>62`P+@#""-Y20``.H$0)'E!``3 -MX1\```H&P(7@`T#$X;@@E>&,/-SEN`#5X0;L@^($0('EH\*@X:`0C>($X([B -M`B"`X`S!@>`?L`/BCN"%X+@QS>$(,!SE$( -M,`SE6`&?Y?[__^M4(9_EN`"5X0`PH.,,P)WE!A6"X!@@C>(``(S@_O__ZP%@ -MAN)V8/_FU.P`XZ82H.$S'H'B'S`&XKX@E>$"$('B&C.@X01!G^4&`%+A`1&% -MX,___XJX(-3A`7!'XM@\`..2!P?@LR"4X0<`4N$U```:NB#4X0!@H.,&4*#A -MD@D"X!`@C>4G``#JH!"-X@,1@>`,$(WE")`1Y0F`&^`?```:!G"$X`"`C>4# -M>X?B$,"=Y0QPA^(((*#AG!"?Y0(PH..P`-?A"9"+X0``C.#^___KV.P`X[C` -MU.$(,*#AOA"4X1@@C>*ZX-3A`<",X-8<`.,,@)WEL0"4X7S`_^98$)_E")`( -MY9#.(.#8[`#CL,#'X8Q5UH/_F -M`1"@XQ^P!>("`%KAJC*@X1&[H.'/__\ZI-"-XO"/O>@`````'`,``"P#``#> -M#```2#&?Y?!%+>D`8*#AL"'3X8S03>(!<*#A``!2X0``H)-%``":U!P`XP,` -MH.&FA*#A`""@X[$PD^$"``#JC!S1Y0$`6.$E```*"5X;H`U>$$4(7@M,#3X0(PH..$$)_E`*"-Y005@>">P"#@_O__ZXR, -MQ>6&:Z#A9#"?Y0``5^.F:Z#AA&2&X&9NAN(,8(;BAF"#X+8`UN$,```*OB#3 -MX0<`4N$)``":I"*@X0$0H.,S+H+B'T`$X@(@@N*V<,;A`C&#X`0@D^411(+A -M!$"#Y8S0C>+PA;WH_O__ZP!`H./1___J`````-X,``#P02WI`&"@X0!`H.,\ -M4)_E!P``ZO[__^NZ$-7A`'"@X08`H.'^___K``!7X04```H!0(3BL#'5X70` -M_^8`$*#C`P!4X?+__SH$`*#A\(&]Z`````#P3RWIS&&?Y9303>(`0*#AQ`&? -MY0@0C>4$$*#A#""-Y;I0UN'^___K`##6Y0``4^-E```*(#_YB``6./B__\:]#"?Y0!@H.,#D*#A6*"3Y08``.JXL-/A -M_O__ZP%@AN)V8/_F``!;X;!PR`$&```*+#"&X@H`5N$$`*#A!1"@X8,PB>`( -M@(/B\?__.@@PG>65!P;@``!3XQX```H$`*#A!1"@X?[__^L`D*#C$*"-X@@P -MH.,*(*#A`)"-Y0&`H.$$L&'@"P"@X0D0H.'^___K!A"@X0HPH.$+`*#A>"#_ -MYK!US>'^___K##"=Y0A@AN`)`%/A!P``"@DPH.$&`*#A"!"=Y0H@H.'^___K -M*#"?Y;@PT^$#8(;@!`"@X040H.'^___K!D"@X7``_^8S_/_K!`"@X930C>+P -MC[WH`````%,#``"`````*#&?Y?!'+>D!<*#ANF#3X0"@H.$&$*#A_O__ZPH` -MH.%Q4/_F!A"@X?[__^L`$*#C<(#_Y@@`H.'^___K``!0XP!`H.$`D*#A#``` -M&O/]_^L`0*#A"`"@X000H.'^___K"1"@X0@`H.'^___K"A"@X00@H.$`,*#A -MM`"?Y?[__^L``%?CEE0DX"8```JD@)_EV7](XA$PU^4&$*#A``!3XQT```H` -M`)?E_O__ZP80H.$`H*#A!`"@X?[__^L``%KA%0``&F0PG^4%`*#ANX080 -MH.'^___K&#"7Y7``_^:``*#AL("3X?\_#^,#`%CA"$"7!01`A0`*```*!0"@ -MX080H.'^___K<1#_Y@%09>"66";@!D"$X`(``.H(`%?A''"'XMK__QH$`*#A -M\(>]Z`````!Q`P``Y`,``(PPG^4`$*#C\$$MZ9Q`@^*Z8-/A_O__ZWAPG^4` -M4*#A"S!4Y0``4^,2```*"#!4Y080H.$%`*#A``!3XP<```K^___K!A"@X0"` -MH.$<`!3E_O__ZP``6.$&```:"@``ZAPP%.4%`%/A`@``&A@P%.4#`%7A!``` -M.AQ`A.('`%3AYO__&@``H./P@;WH`0"@X_"!O>@`````'`0``+0PG^7P3RWI -M`Z"@X8S03>*Z,-/A"("-X@!PH.$!8*#A`E"@X0@`H.'_$*#C@""@XP0PC>4` -M0*#C_O__ZQ8``.K^___K=#"?Y000G>6X,,WA`#"@X[@QS>$`L*#A"0"@X?[_ -M_^L!,*#CN#?-X;@"S>%,`)_E_O__ZX04A>``,*#C"""@X0L`H.'^___K``"@ -MX_[__^NX,-KA`T"$X`8`5.$'D(3@`1"@XPD`H.'C__\Z``"@XXS0C>+PC[WH -M``````#R__].04Y$1#2?Y?!/+>E'WTWBNF#3X0-`H.$0`(WE`("@XP80H.$& -M<*#A_O__ZP@0H.%P`/_F%`"-Y0@`H.'^___K`%"@X;L``.H(`*#A`!"@X_[_ -M_^L%`%#A`*"@(P&@H#,`,&7@`0!3XPHPH)$!,(J#`&"@X0``4^.J```*T`.? -MY040H.'^___K``!:XP@```H`H*#C.OW_ZP&@BN)ZH/_F!0!0X0$``(H4`%KC -M^/__&@!@H.'B+`CC`5"%XK(`E.&2``#JL!#1X0(P@^(!`%7AC0``"@,0A.`! -MP(+B``!2X2,;@>+N$('B?"#_YO3__SH%`%;AA```"M:L`.-4`Y_E!1"@X?[_ -M_^NZ,)3A!0!3X0@``!H:_?_KV"P`XP`PH..R()3A`,"@X;K`A.&7``'@EP4` -MX/[__^L&-`#C!L"@X0"@H..SL)3A!#!#XK.0E.$!.Z#CLS"4X0-@H.$-``#J -M","-Y?[__^L(P)WE@1^!XH$0A.`"(('BLA#1X04`4>$$```:#&"@X;#`PN&P -M`=3A`#"@XQ$``.IZ(/_F"0"*X`L`4N$&$*#A`:"*XNO__SH,8*#A]/__ZK`@ -MTN$!,(/B`@!5X04``!IF/H'B?,*?Y0PP@^*#,(S@MF##X08``.IS$/_F@R"$ -MX```4>'-+H+B#B""X@,0H.'N__\Z6""4Y0\`4N,`,*"3!P``F@0``.JX`-'A -M"!"!X@4`4.$"```:L&#!X3"BG^4&``#J+!"#X@$`@^("`%/A@1"$X'`P_^;R -M__^:]O__ZA$PVN4'$*#A``!3XP4```H(`)KE_O__ZP``5>$`(*`#$2#*!0,` -M``KH,9_E`P!:X1R@BN+Q__\:O#34X040H.$8H(WB"`"@X04`4^&\9,0!EP8& -MX`#`H`,`(*`#OL3$`5`@A`7^___K"B"@X08`H.$`$*#C"#"@XP#`X.,`P(WE -M_O__Z[C"W>'R[*#CEP4!X`'`C.(!4*#CN,+-X;A8S>'_P.#C1E^-X@8`H.$* -M,*#A!R"@X;S@A>&X@\WA_O__ZP<``.H!4(7B=5#_Y@Q0C>4&`%7A`#"@DP,@ -MH)%J__^:#&"-Y0&`B.(,4)WE>(#_YA3`G>4,`%CA0/__.A`@G>4!$*#C$+&? -MY0=@H.$!D$+B\*"?Y0D`H.$+<*#A_O__ZP`0H.,!4*#A`8"@X9Q`BN*D`(OE -M"0"@X?[__^L&$*#A_O__Z[(SVN$&$*#A`9"`XA``G>5YD/_FL)/*X0,P:>"T -M,\KA_O__ZPD0H.&V`\KAJ`"?Y?[__^L+,%3E``!3XQ,```H<`!3EI#"7Y0,` -M4.$/``"*"X!$Y10@%.6D,)?E`P!2X0H``)H&$*#A_O__ZP40H.$`(*#A9`"? -MY?[__^L4`!3E!A"@X?[__^MP`/_FLOO_ZP%0A>(<0(3B(`!5X^3__QHP,)_E -M!A"@X:0`D^7^___K`!"@X2@`G^7^___K1]^-XO"/O>@`````K`,``,,#``"` -M````Y`,```````#C`P``$00``$,$````,9_E\$&`(*#AN!'8X4@PF(6R,).!`2"$X@,`4>$C```J -M!0!3X01PH)$#4*"1@`````>P0``&`QG^5P0"WI7$&?Y910D^4!,*#C -M``!5X[0QQ.$%```*`0!%X@`0H./^___KNA#4X?[__^L`4*#A+$&?Y0%0A>(@ -M,9_E=5#_YKH0U.&4`)/E_O__Z[(SU.$%$*#AL%/$X0-09>"T4\3A!%"@X;8# -MQ.'X`)_E_O__Z^(\"..PP]3ALP"4X0`PH..T(]3A@`"@X0(``.JP$-'A#`!1 +M$*#A!P"@X?[__^L``%#C#```"@<0H.%\`)_E_O__ZPQ`G>4)$*#A!`!7X00` +MH.$$<*#A`$#@`Q,```K^___K<(#_YN+__^I(,)_ENB'3X04`4N&Z4<,Q``!6 +MXP4```JP,-;A#PI3XP(```KR#%/CL%?&X;"$Q@$'`*#A`!"=Y08@H.$$,)WE +M_O__ZP0`H.$4T(WB\(^]Z``````<````\$\MZ51TG^7B/`CCX&P(XP#`H..) +MWTWBL\"'X20]">,"ZZ#C`!"@XP-0E^<((*#CMN"'X0`PX.,D!)_E!8"@X;I` +MU^$<,HWE&#*-Y?[__^NV()?A_Q"@XP@$G^4!8*#A!%"@X8(@H.'^___KO*#7 +MX9H$">`B``#J`,"@XP#`C>7^___K`3"'X@``4.,*```:N"'=X0$PAN(/"E+C +M$P``&@``5.,B[HWB```%/C!P``R@&@BN)4$Y_EO##1X3(P@^(#`%KA`'"@,P=`H#'L__\Z=F"O +MYD`#G^4&$*#A!4"@X?[__^L!`';C"%"@X0,``!HH`Y_E_O__ZP8`H.'!``#J +M&**=Y000H.$*`*#A_O__ZQQBG>4&`*#A`7"@X000H.'^___K`0!7X0&`H.$% +M```*`0!VXP,```H!`'KC`@``"@$`5^$```":"F"@X040H.$8((WB"#"@XP8` +MH.$`P.#C`,"-Y?[__^NT,I_E(BZ-XK`"G^4BSHWBK)*?Y;,0DN$0,(/BL`"< +MX;,@DN$0,(/BF**?Y;,PG.$``(WED`*?Y;``G.$,`(WEB`*?Y;K@G.&PL)SA +MN0"40L(WE"`"-Y7`"G^7^___K"`!7X2<```H$$*#A!@"@X?[__^LB +M+HWBNA"2X;D@DN&4`0/@`0!0X1PRC048,HT5E`("``@RG^64`@(0&"*-!1PB +MC16\(-/A`@!1X00``#H(,I_E(LZ-XK,PG.$"`%/A`0``*@@"G^5=``#J!`*? +MY1A@C>+^___K!1"@X08@H.$`,*#C&`*=Y?[__^L&(*#A'`*=Y040H.$`,*#C +M_O__ZP``H./^___KS!&?Y2+NC>*PP9_EX@P(XX0QG^6Q$)[AO,">X;0AG^6T +M$,/A`!"@X[`0@^'J'`CCLB">X;'`@^$"$('B@,&?Y;(AP^&P(+R__\Z@B"@X040H.$""U+C +M`BN@H_``G^7^___K&&*=Y1QRG>4$$*#AU%"?Y0<`5N$&`*`Q!P"@(?[__^OF +M/`CC!!"@X;,`A>$'`%;A!@"@(0<`H#'^___KZ#P(XP00H.&S`(7A!@"@X?[_ +M_^NT,-7A(R2@X00`4N/D+`CCLA"%X0,0H!&X`)\50BZ@$P0``!JP$=7AOB#5 +MX0(`4>$"```ZH`"?Y?[__^L2``#JH@!1X00``"J,`)_E_O__Z[XPU>$C,4/@ +ML#'%X31`G^7B7`CC=`"?Y;40E.'^___KOB#4X;4PE.$B`E/A``"@DP(``)I8 +M`)_E_O__ZP``X..)WXWB\(^]Z`````#FC```[HP``#\```!9````^/W__RC^ +M__](_O__./[__UC^__]H_O__;0```)\```!.04Y$"/[__QC^___.````^0`` +M`#,!``!+`0``\$\MZ7RAG^7J/`CC`("@X:/?3>(!D*#ALU":X0*PH.&Z8-KA +ME@4%X`4`H.$2_?_K5#&?Y0,`6.%P<+_F#```&@(LC>(`0*#C\SR@XP<`H.&X +M,,+A!A"@X0A`C>4,0(WE$$"-Y?[__^L$,*#A@B^-X@T``.H409_E!`!8X0X` +M`!H"+(WB\SR@XP<`H.$&$*#AN##"X0B`C>4,D(WE$+"-Y?[__^N"+XWB`#"@ +MXP4`@>`($(WB_O__ZS```.K0,)_E`"!7X@$@H!,#`%CA`""@$P``4N,"@*#A +M*```"K@`VN$(D(WB@J^-X@$PH.,%`&#@"1"@X0H@H.$'`(#@`,#@XP#`C>7^ +M___K"#"=Y00`4^$:```:`CR-XKB`T^'S#%CC%@``&@!`H.-H`)_E_O__ZP0P +MH.$&(*#A$!"=Y0P`G>7^___K`BR-X@<`H.$&$*#AN(#"X0A`C>4,0(WE$$"- +MY?[__^L*(*#A!#"@X04`@>`)$*#A_O__ZP0`H.'^___KH]^-XO"/O>@````` +M``!351$14U4B(E-53D%.1&@QG^7B'`CC\$4MZ0`@H.&Q`)/A`A!!XH303>*Z +M4-/AL1"3X0``4>$`$*"#`P``BDP``.JPP-SA`@!&P)\WA +M`2"!XK,@A.&T,-3ANL"4X;#FS>&P,&X,)3AL,3-X;`US>$/ +M.J#CL##-X?[__^NWP)3AN@"4X04`7.$,```Z#2"@X8`0G^4`,*#C`,"@XY4` +M`."WP(3A_O__Z[@`E.$-(*#A8!"?Y0`PH..5``#@#@``ZKC@U.$-(*#A2!"? +MY0`PH.,.P(S@?,#_YK?`A.&5P"#@_O__Z[<`E.&XP)3A#2"@X2`0G^4`,*#C +ME0P@X/[__^L``*#C_O__ZX30C>+PA;WH`````$Y!3D3NC```<$`MZ701G^5T +M(9_E`%"@X?[__^ML09_E`&"%X&@!G^7^___KN"#4X6`1G^4&`*#A_O__Z[H@ +MU.%4$9_E`&"&X`8`H.'^___KL"'4X401G^4`8(;@!@"@X?[__^NR(=3A-!&? +MY0!@AN`&`*#A_O__ZP@T`.,D$9_ELR"4X0!@AN`&`*#A_O__ZP8T`.,0$9_E +MLR"4X0!@AN`&`*#A_O__ZR`@E.7\$)_E`&"&X`8`H.'^___K+""4Y>P0G^4` +M8(;@!@"@X?[__^NZ(=3AW!"?Y0!@AN`&`*#A_O__Z[@AU.',$)_E`&"&X`8` +MH.'^___KOB'4X;P0G^4`8(;@!@"@X?[__^N\(=3AK!"?Y0!@AN`&`*#A_O__ +MZ[03U.$`8(;@(`"4Y?[__^N0$)_E`""@X08`H.'^___K7""4Y8`0G^4`8(;@ +M!@"@X?[__^LX()3E!P@+WH;0$`````````````<0$``(+N__\Z``!7XT1`G^4(-``#`E0`XS@@GP6U`)3A +MLQ"2`0$`@.(!$$$"LQ""`08T`.,!&Z#CLR"4X;$0E.$!($+BLR"$X?[__^NU +M$(3A"0"@X?B/O>@`````9#&?Y?!/+>D`0*#ALK/3X1303>(+`%#A`("@(T@@ +MDS6`,*`QLX"2,08D`.,X,9_ELG"3X0$KH..RH)/A"@!7X4<```H"((+B2`"3 +MY0!@H.,#P*#ALB"3X0&0H.,,`(WE!E"@X0@@C>41``#J!,"-Y?[__^L$P)WE +M`3")XH$?@>*!$(S@LB#1X0L`4N&"$*#A`P``*@P`G>6Q$)#A"`!1X0```(H) +M4*#A`@!4X7.0_^8K```*=C#_Y@@@G>4'`%/A"A"@X0(`AN`!8(;BYO__.@@` +M`.K^___K`5"%XG50_^:!'X'B@1")X+(PT>&R0,'A`T"@X0```.ILD)_E"#"= +MY0<`5>$*$*#A7&"?Y0,`A>#O__\Z!%0`XP$[H.,&)`#C`7"'XK4`EN&S$);A +M@3^`XK)PAN$!`(#B@S"&X+)`P^'^___KOC'6X00P0^(#`%CA"#0`H[,@EJ&U +M$(;A`2""HK,@AJ$4T(WB\(^]Z`````#Q3RWI'$&?Y0@T`.,!*Z#CLU"4X0(P +M0^*R<)3ALZ"4X00P0^('$*#ALS"4X0J@9>!ZH//F"@"@X?[__^L``%7C@1^! +MXH$0A."R8-'A,@``"K(SU.',@)_E!@!3X88PH($`,*"32""4A;,PDH&^(=CA +M`P!2X0&P18(`4*"##```BB4``.K^___K`0")X@%0A>)U4/_F@4^!X@<0H.'^ +M___KA$"(X($?@>*!$(C@LA#1X;(0Q.$+`%7A"I"%X`<0H.$)`*#A7$"?Y>W_ +M_[H$5`#C`1N@XP@T`.,&)`#CM<"4X;$`E.&RX)3A`!"@X0``C."SP)3A`>!. +MX@$`0.*RX(3A`2!,XK,@A.'^___K!@"@X;40A.$$T(WB\(^]Z`30C>+P3[WH +M$___Z@````"(,)_E!A0`XQ!`+>FT(=/AL1"3X0$`4N,()`#CLB"3X1@``!H! +M(&+@A`G^7_/P_CC-!-XK`DU.%(<)3E +M`P!2X;H@U.&X8-3AM(34X00@C>4#```:S?__ZP`PH..R-,3AL`3$X:Q`G^4$ +MP)WELC34X9@V(^`,`%/A!0``VK`$U.$;___KP?__ZP`@H..R),3AL`3$X7PP +MG^6&I*#A!,"=Y0!0H.,#0*#A;)"?Y;`TT^$(L(WBG`,#X`0PC>41``#JLA34 +MX50`G^6X4'^___KL@34X0<0H.$$P)WE`#"@XPL@H.$*<(?@ +M``",X'50_^;^___KLC34X0,PAN"R-,3A"`!5X>O__SJ,T(WB\(^]Z`````!: +MI?__[@(``/!/+>F@0I_EI-!-XIP"G^6P,=3A?S^#X@,P@^*C-*#A%#"-Y?[_ +M_^O4+`#C`#"@XP3`H.$#<*#AL@"4X0$0H.,#``#J`B&,X,PLDN41)!+@=7#_ +M%G,@_^8?0`/B``!2X0%0A^(!,(/BHB*@X?3__SH``%?CB@``"BQ"G^787`#C +MN!#4X;4@E.&Z,-3AD24$`!/A'P``"@;`A>`#0,3AN""5 +MX8P\W.6X`-7A!NR#X@1`@>6CPJ#AH!"-X@3@CN("((#@#,&!X!^P`^*.X(7@ +MN#'-X0@P'.5R(/_F`A"@X;0@SN$:.X/AN""%X0@P#.58`9_E_O__ZU0AG^6X +M`)7A`#"@XPS`G>4&%8+@&""-X@``C.#^___K`6"&XG9@_^;4[`#CIA*@X3,> +M@>(?,`;BOB"5X0(0@>(:,Z#A!$&?Y08`4N$!$87@S___BK@@U.$!<$?BV#P` +MXY('!^"S()3A!P!2X34``!JZ(-3A`&"@XP90H.&2"0+@$""-Y2<``.J@$(WB +M`Q&!X`P0C>4(D!'E"8`;X!\``!H&<(3@`("-Y0-[A^(0P)WE#'"'X@@@H.&< +M$)_E`C"@X[``U^$)D(OA``",X/[__^O8[`#CN,#4X0@PH.&^$)3A&""-XKK@ +MU.$!P(S@UAP`XPR`G>6Q`)3A?,#_YE@0G^4(D`CED,X@X-CL`..PP,?AC%S$ +MY;[`A.&XH("8(;B%""=Y76@_^8!$*#C'[`%X@(`6N&J,J#A +M$;N@X<___SJDT(WB\(^]Z``````4`P``)`,``-X,``!(,9_E\$4MZ0!@H.&P +M(=/AC-!-X@%PH.$``%+A``"@DT4``)K4'`#C`P"@X::$H.$`(*#CL3"3X0(` +M`.J,'-'E`0!8X24```IR0/_F`A"`X`,`5.$!((+B]___.@`@H.,!`*#CY!"? +MY0,``.H,P8'@S,R"QX)7AN@#5X010A>"T +MP-/A`C"@XX00G^4`H(WE!!6!X)[`(.#^___KC(S%Y89KH.%D,)_E``!7XZ9K +MH.&$9(;@9FZ&X@Q@AN*&8(/@M@#6X0P```J^(-/A!P!2X0D``)JD(J#A`1"@ +MXS,N@N(?0`3B`B""XK9PQN$",8/@!""3Y1%$@N$$0(/EC-"-XO"%O>C^___K +M`$"@X]'__^H`````W@P``/!!+>D`8*#A`$"@XSQ0G^4'``#J_O__Z[H0U>$` +M<*#A!@"@X?[__^L``%?A!0``"@%`A.*P,=7A=`#_Y@`0H.,#`%3A\O__.@0` +MH.'P@;WH`````/!/+>G,89_EE-!-X@!`H.'$`9_E"!"-Y000H.$,((WENE#6 +MX?[__^L`,-;E``!3XV4```IR_O_K`'!0XF(```H$`*#A_O__Z[`QUN$#`%#A +M`@``*G``_^8'$*#A_O__ZWAAG^4`@*#C$3#6Y040H.$``%/C$P``"@"@EN4* +M`*#A_O__ZP40H.$`D*#A!`"@X?[__^L``%GA"@``&@H`H.$%$*#A_O__ZP$P +MA^(?`%CCE0,#X`0PAN65%R'@`!"&Y1@``)H$``#J`8"(XAQ@AN)X@/_F(`!8 +MX^+__QKT,)_E`&"@XP.0H.%8H)/E!@``ZKBPT^'^___K`6"&XG9@_^8``%OA +ML'#(`08```HL,(;B"@!6X00`H.$%$*#A@S")X`B`@^+Q__\Z"#"=Y94'!N`` +M`%/C'@``"@0`H.$%$*#A_O__ZP"0H.,0H(WB"#"@XPH@H.$`D(WE`8"@X02P +M8>`+`*#A"1"@X?[__^L&$*#A"C"@X0L`H.%X(/_FL'7-X?[__^L,,)WE"&"& +MX`D`4^$'```*"3"@X08`H.$($)WE"B"@X?[__^LH,)_EN##3X0-@AN`$`*#A +M!1"@X?[__^L&0*#A<`#_YDW\_^L$`*#AE-"-XO"/O>@`````2P,``(`````H +M,9_E\$'"?Y0!0H.$+,%3E``!3XQ(```H( +M,%3E!A"@X04`H.$``%/C!P``"O[__^L&$*#A`("@X1P`%.7^___K``!8X08` +M`!H*``#J'#`4Y04`4^$"```:&#`4Y0,`5>$$```Z'$"$X@<`5.'F__\:``"@ +MX_"!O>@!`*#C\(&]Z``````D#H*#AC-!-XKHPT^$(@(WB +M`'"@X0%@H.$"4*#A"`"@X?\0H..`(*#C!#"-Y0!`H./^___K%@``ZO[__^MT +M,)_E!!"=Y;@PS>$`,*#CN#'-X0"PH.$)`*#A_O__ZP$PH..X-\WAN`+-X4P` +MG^7^___KA!2%X``PH.,((*#A"P"@X?[__^L``*#C_O__Z[@PVN$#0(3@!@!4 +MX0>0A.`!$*#C"0"@X>/__SH``*#CC-"-XO"/O>@``````/+__TY!3D10-)_E +M\$\MZ8??3>*Z8-/A`T"@X1``C>4`@*#C!A"@X09PH.'^___K"!"@X7``_^84 +M`(WE"`"@X?[__^L`4*#AO@``Z@@`H.$`$*#C_O__ZP4`4.$`H*`C`:"@,P`P +M9>`!`%/C"C"@D0$PBH,`8*#A``!3XZT```K<`Y_E!1"@X?[__^L``%KC"``` +M"@"@H.,Z_?_K`:"*XGJ@_^8%`%#A`0``BA0`6N/X__\:`&"@X>(<".,!4(7B +ML0"4X94``.JP$-'A`C"#X@$`5>&0```*`Q"$X`'`@N(``%+A(QN!XNX0@>)\ +M(/_F]/__.@4`5N&'```*UJP`XV`#G^4%$*#A_O__Z[HPE.$%`%/A"```&AK] +M_^O8+`#C`#"@X[(@E.$`P*#ANL"$X9<``>"7!0#@_O__ZP8T`.,&P*#A`*"@ +MX[.PE.$$,$/BLY"4X0$[H..S,)3A`V"@X0T``.H(P(WE_O__ZPC`G>6!'X'B +M@1"$X`(@@>*R$-'A!0!1X00``!H,8*#AL,#"X;`!U.$`,*#C$0``ZGH@_^8) +M`(K@"P!2X080H.$!H(KBZ___.@Q@H.'T___JL"#2X0$P@^("`%7A!0``&F8^ +M@>*((I_E##"#XH,P@N"V8,/A!@``ZG,0_^:#((3@``!1X[__SI8()3E#P!2XP`PH),'``":!```ZK@`T>$($('B!0!0X0(``!JP8,'A +M/**?Y08``.HL$(/B`0"#X@(`4^&!$(3@<##_YO+__YKV___J$3#:Y0<0H.$` +M`%/C!0``"@@`FN7^___K``!5X0`PH`,1,,H%`P``"O3AG^4.`%KA'*"*XO'_ +M_QJ\--3A&*"-X@@`H.$%`%/AO&3$`9<&!N``$*`#`""@`[X4Q`%0((0%!1"@ +MX?[__^L*(*#A!@"@X0`0H.,(,*#C`,#@XP#`C>7^___KG.&?Y0HPH.&&KXWB +ME,&?Y9<%`>#R7*#COE"*X2#@CN(&`*#AO&":X;Z`BN%0X([B`5"@XP%@AN(' +M(*#AOE"*X;Q@BN'^___K!P``Z@%0A>)U4/_F#%"-Y08`5>$`,*"3`R"@D6?_ +M_YH,8(WE`8"(X@Q0G>5X@/_F%*"=Y0H`6.$]__\Z$."=Y0$0H.,8L9_E!V"@ +MX0&03N+PH)_E"0"@X0MPH.'^___K`!"@XP%0H.$!@*#AG$"*XJ0`B^4)`*#A +M_O__ZP80H.'^___KLC/:X080H.$!D(#B$`"=Y7F0_^:PD\KA`S!IX+0SRN'^ +M___K"1"@X;8#RN&P`)_E_O__ZPLP5.4``%/C$P``"AP`%.6D,)?E`P!0X0\` +M`(H+@$3E%"`4Y:0PE^4#`%+A"@``F@80H.'^___K!1"@X0`@H.%L`)_E_O__ +MZQ0`%.4&$*#A_O__ZW``_^:O^__K`5"%XAQ`A.(@`%7CY/__&C@PG^4&$*#A +MI`"3Y?[__^L`$*#A,`"?Y?[__^N'WXWB\(^]Z`````"D`P``NP,``(````#D +M`P```/[__Q#^__\`````VP,```8$```X!````#&?Y?!'+>G_;P_CL''3X090 +MH.&XDM/AMJ/3X:>0B>#@@)_E>9#_Y@<`6>$)D&>`>9#_A@H`6>$*D*`Q"4"@ +MX0X``.K^___KLA/8X0`PH.,``%'A@""@X;@1V.%(,)B%LC"3@0$@A.(#`%'A +M(P``*@4`4^$$8*"1`U"@D7)`_^8'`%3A!`"@X0`0H./L__\Z"D"@X6QPG^4. +M``#J_O__Z[(3U^$`,*#C``!1X8`@H.&X$=?A2#"7A;(PDX$!((3B`P!1X0T` +M`"H%`%/A!&"@D0-0H)%R0/_F"0!4X00`H.$`$*#C[/__.A@PG^4%$*#A%`"? +MY09`H.&X4(!8$+B[A"!X@(P@^*L0)_E]/__&K@1U.&Z,=3A M0`"!XK0CQ.&\$<3A<"#_YKXAQ.$#`%+A#```*D!00^(@`)3EM!/4X750_^:^ M,<3AO%'$X?[__^MP`/_F!0!0X0,PH#.3```P0`&@,;P!Q#%,,)_E`Q"@X;`C MT^&",*#A"```ZD@`D>4#P(#@LP"0X0(P@^(``%#C`@``&KP!T>$``%#CL`#, -M$;(#T>$``%+A`2""XO+__SIP0+WH_O__Z@``````````J`0``#0QG^7P02WI +M$;(#T>$``%+A`2""XO+__SIP0+WH_O__Z@``````````G00``#0QG^7P02WI M`P!0X8#03>(`0*#A!```&B`AG^7&R<)7A!@!3X04``#KH`)_E_O__ZP`` MH./^___K`!"@X[@0A>'4,)_E`P!4X08``!J\()_EW#P`X[,PDN$``%/C`0`` @@ -242,28 +242,28 @@ M&O[__^O^___K/3N@X[`PS>&4,)_E`P!4X04``!J,()_E`#"@X[`PS>'@``%-5```` -M`,0$``!.04Y$$1%35>$$``#P02WI"3#0Y0!0H.$``%/C\(&]"&PRG^40+0GC +M`+D$``!.04Y$$1%35=8$``#P02WI"3#0Y0!0H.$``%/C\(&]"&PRG^40+0GC M9$*?Y0`0H.,"`)/G)!"#Y0``5>&Z8-/A`A"#!U@PE.4!`'/C!0``&E0PE.4! M`'/C`3"#`E0PA`58,(0%60``"B1"G^54,)3E!@!3X5D``#H8`I_E_O__ZU@0 ME.5<,)3E`""@XP\`4>-4((3E`3"#XEPPA.4I```:L`;4X0(PH.$"P(3@`>"# MXIT(`P-SE``!X;#FS.$!`(/B4`(*#C`C"@X5@0E.6!$(3@L!;1X;P0Q>%><-3E5`"4Y?%\A^,,<([G$,"5 MY;SEU.&6`2#@$!`$XP'@C.<0$('B$,"5Y0#@E>4!X(SG$!"!XA#`E>6RX-7A M`>",YQ`0@>(0P)7E!."5Y0'@C.<0$('B$,"5Y;;@U>$!X(SG$!"!XA#`E>4! M((SG$!"5Y0$I@>+^___K5#"4Y;@@U.$#,(+@5#"$Y?"!O>@```````!3512= M``!S0"WI9`"?Y?[__^M@,)_E`2#3Y0``4N,$```*$"T)XP(`D^<``%#C```` M"D[__^M``)_E`,"@XS3@G^4,$*#A#""@X0$PH..48)#EF%"0Y;!!WN$&8.#A -MN@#>X0;@9>``P(WEE.`@X/[__^M\@+WH$`4`````````````$$`MZ0!`4.(( +MN@#>X0;@9>``P(WEE.`@X/[__^M\@+WH!04`````````````$$`MZ0!`4.(( M```:*#"?Y0$@T^4``%+C!```"A`M">,"`)/G``!0XP````HO___K!#"?Y0%` -MP^40@+WH`````%0PG^400"WI%"33Y0$`4N,$```*%233Y3P`4N,!((+B%23# -MY08``)HP`)_E_O__ZR0@G^4`,*#C`P"@X14TPN7^___K$""?Y0$PH.,#`*#A -M%#3"Y1!`O>C^___JT+P,`",%``#P1RWI`$"@XXQ@G^4`4*#AB)"?Y12@H.,$ +MP^40@+WH`````%0PG^400"WI&"33Y0$`4N,$```*&233Y3P`4N,!((+B&23# +MY08``)HP`)_E_O__ZR0@G^4`,*#C`P"@X1DTPN7^___K$""?Y0$PH.,#`*#A +M"Y1!`O>C^___JR-P,`!@%``#P1RWI`$"@XXQ@G^4`4*#AB)"?Y12@H.,$ M<*#A$(T)XP0PAN`G.X/BZ#"#X@8PT^6:DR/@`P!5X1(``!H$<(7E"#"6YP,` M5>$(<(8'`0``"@4`H.'\_O_K"7#%Y00PAN`!0(3B)RN#X@(PH.'I((+B=$#_ MYN@P@^(&(-+E(`!4XP8@P^7T__\:`4"$XG1`_^8?`%3CX?__FO"'O>@````` @@ -273,8 +273,8 @@ M@@=P@+WH`````&PPG^5S0"WI`2#3Y0``4N,$```*$"T)XP(`D^<``%#C```` M"L?^_^M(`)_E_O__Z_[__^M``)_E-."?Y0#`H.,,$*#A`3"@XY1@D.4,(*#A MF%"0Y;!!WN$&8.#AN@#>X0;@9>``P(WEE.`@X/[__^M\@+WH`````!$14U4` M````\$$MZ7!!G^4"@*#A_S\/XX#03>(`8*#AO"34X0%PH.&Z4-3A`P!2X00` -M`!KS^?_K`#"@XU`PA.6^-,3AO`3$X31!G^6X(-3AOC34X0,P@N`%`%/A"``` -MVKP$U.%`^?_KYOG_ZP`PH..^-,3A4#"4Y0$P@^)0,(3EO`3$X?PPG^4#`%CA +M`!KO^?_K`#"@XU`PA.6^-,3AO`3$X31!G^6X(-3AOC34X0,P@N`%`%/A"``` +MVKP$U.$\^?_KXOG_ZP`PH..^-,3A4#"4Y0$P@^)0,(3EO`3$X?PPG^4#`%CA M%0``&NQ`G^4`<*#C&!"6Y0!@H..P8LWA#2"@X;QDU.$`,*#CO@34X5#@E.7, MP)_EE08@X%Y8Y^<,P(7AL'/-X;!TS>&P=&PX!2R.?G`S", @@ -282,7 +282,7 @@ MX;`AS>&P,,WA_O__ZP40H.&P`LWA"`"6Y?[__^L8$);EO.34X0T@H.&P=,WA M`#"@X[)QUN&^Q-3AL'7-X;Q@UN&P9LWA`&"@X[!GS>&P`\WAE@```````!350#U__\1$5-5>#*?Y?!/ M+>D`0*#ANH#3X9S03>(!H*#AN!#3X0@`H.'^___K%%#4Y0``5>-P`/_F"`"- -MY8D```H``%KC`#"@XQ0PQ.4!```:B?G_ZP"@H.$*$*#AL@'4X?[__^L$,)3E +MY8D```H``%KC`#"@XQ0PQ.4!```:A?G_ZP"@H.$*$*#AL@'4X?[__^L$,)3E M'"*?Y00`H.$#,&C@"A"@X0`PA.4`4*#C??__ZY@*`N`(,)WE])&?Y0BPH.$! M,$/B%#"-Y1`@C>5=``#J&#"4Y84@H.'_SP_CLA"3X0P`4>$%(*`1`7"@$P8` M`!H1``#JM@"3X;S`D^$!`(#B#`!0X0@``!I^"' @@ -293,10 +293,10 @@ MH.$8((WB`,#@XP#`C>7^___KN#+=X0(P@^)S,/_FN#+-X0$`4^,%```:N"'= MX>0PG^4!((+B_R`"X@,P@N&X,4!<$CB MN"#9X;BES>%W$&`*#A_O__Z[@PV>$#8(;@N!#9X08`H.$0 MX)WE`#"@XY$'`N"1Y2'@!5"'X'50_^9R(/_F_O__ZP@@G>4"`%7AGO__.F0@ -MG^4$`*#A`!"@XPN`H.$/___K"Q"@X0@`E.4!4*#C_O__ZW``_^9B^/_K"Q"@ -MX0``E.7^___K<`#_YEWX_^L(,)WE_Q"@XQ@`E.6#(*#A_O__ZP4`H.&(`L*#A`0R@XQP0C>6Z -M$-;A)""-Y1`0C>7^___K``!0XPP`C>7B```*`0R@X[J`UN'^___K`%!0XE$` +MG^4$`*#A`!"@XPN`H.$/___K"Q"@X0@`E.4!4*#C_O__ZW``_^9>^/_K"Q"@ +MX0``E.7^___K<`#_YEGX_^L(,)WE_Q"@XQ@`E.6#(*#A_O__ZP4`H.&(`L*#A`@R@XQP0C>6Z +M$-;A)""-Y1`0C>7^___K``!0XPP`C>7B```*`@R@X[J`UN'^___K`%!0XE$` M``J\!-;A_S\/XP,`4.%+```*F```X-3S_^N\Q-;AN)#6X0`0H.,%(*#A"#"@ MXY@,#.`,P&G@<`#_YKX$QN$`D(S@``#@XP``C>4)`*#A_O__ZP``4.,Y```: ML#+5X0``4^,V```*L"/5X0``4N,S```*L!35X0``4>,+<*`1*```&BX``.JR @@ -313,13 +313,13 @@ MV.4`P*#C`,"-Y?[__^L``%#C#@``&@S@G>4?`%7C"Z"@X0!PWN6P`M[AL#'> MX2@`C>4'>(/A!0``BK`VWN$&(*#AN!#8X00`H.&1`P'@T_+_Z[@PV.$*L*#A M`V"&X'9@_^8@,)WE"0"&X``0H.,,()WE`P!6X0:@H.'?__^Z'P!5XRR@G>4& M``"*`5"%XBC`G>4!X*#C#'"$Y750_^81X,3ELL'$X1@`G>4``%OA'@``BK0` -MG^7^___K!A0`X[$PF.$``%/C`&"@$P,``!KJ+`CCLF"8X08`H.&!]__K`3"@ -MXP0`H.$`$*#C%##$Y8;^_^L``%;C`,"@XQ'`Q.4*```*'OC_ZP`0H.$`D*#A +MG^7^___K!A0`X[$PF.$``%/C`&"@$P,``!KJ+`CCLF"8X08`H.%]]__K`3"@ +MXP0`H.$`$*#C%##$Y8;^_^L``%;C`,"@XQ'`Q.4*```*&OC_ZP`0H.$`D*#A ML@'4X?[__^L0X)WE!@"@X0`PH.,.(*#AG@D!X/[__^L4`)WE!*"*X@$`@.(4 M`(WE%!"=Y20@G>4"`%'A?O__.@P`G>4TT(WB\$^]Z/[__^HTT(WB\(^]Z``` -M``"`````204``)0PG^7P02WIV2]#X@!`H.$$`%+A'```&A$PU.4``%/C\(&] +M``"`````/@4``)0PG^7P02WIV2]#X@!`H.$$`%+A'```&A$PU.4``%/C\(&] M"`0`H.$`$*#C6O[_ZP!P4.(1```:8&"?Y0!0E.6Z$-;A!0"@X?[__^L$()3E -M"`"4Y0`%$*#A_O__Z[H0UN$(`)3E_O__ZW``_^8\ +M"`"4Y0`%$*#A_O__Z[H0UN$(`)3E_O__ZW``_^8X M]__K`#"@XQ$PQ.7P@;WH`P!2X1P@@N+=__\:\(&]Z.0#````````\$$MZ0`0 MH./^___K9#"?Y8!`@^+Y;X/BNE#3X0!PH.$1,-3E!1"@X0``4^,+```*``"4 MY?[__^L%$*#A`("@X0<`H.'^___K``!8X0,``!H$`*#A%$#4Y?[__^L#``#J @@ -333,7 +333,7 @@ MBN(<0(3B>J#_YB``6N/I__\:.#&?Y=E/0^(1(-3E``!2XPT```H#`%3A'$"$ MXOG__QH<,9_E#DU#XA`@U.4``%+C`@``&@0`H.'^___K`@``ZAQ`A.(#`%3A M]O__&@<`H.$%$*#A_O__ZP@@C>(",*#C``#@XP``C>4'`&'@`!"@X_[__^L( M,-WEN''=X040H.$(`*#A`7"'X@-XA^`,<(3E_O__ZP<0H.%P]Z`````#D`P````0``'!`+>G$8)_EMC'6X0$` @@ -341,497 +341,494 @@ M4^-P@+T8`""@X[I0UN&V(<;A_O__Z[PQUN$`0*#AN`'6X0,`4.$"``":``!C MX'``_^;^___KA&"?Y;HAUN&^,=;A`P!2X7"`O3@$`*#A`!"@X_[__^NR,];A M!!"@X94$!.```%/A@`"@@0`@H)-(,):%L""3@4@`G^7^___K/#"?Y0`@H.,$ M`*#AM"'#X2P@D^4!((+B+""#Y?[__^L``%#C`@``&@0`H.'^___K_O__ZP@P -MG^4!(*#CM"'#X7"`O>@`````@04```@QG^7P3RWI`&"@X;B`T^&$T$WB^`"? -MY0)0H.$!H*#ANG#3X0V0H.'^___KB+2@X2\``.IS4/_F_O__Z]0PG^4'$*#A -M`$"@X08`H.$.(-3E`S""X;`PS>&\,-3AL#'-X?[__^L'$*#AL`+-X0@`E.7^ -M___K!Q"@X;`#S>$``)3E_O__ZP<0H.$`,*#CL#7-X;`$S>$&`*#A_O__ZPA@ -MAN`!`*#A"!"@X?[__^L`,*#C"A"@X;`WS>$-(*#A`#!5X@$PH!,+H(K@L`;- -MX0``E.7^___K`#"4Y00@E.4#,(C@`#"$Y0(`4^$!```:!`"@X?[__^L``%7C -M`3!%X@8`H.'+__\:!0"@X830C>+PC[WH````````4U4`\O__0"*?Y?A/+>D\ -M,I_END#2X0!@H..H4)/E`0!UXP0``!H!8(;B!#"#X@H`5N/X__\:^(^]Z!`R -MG^4$<*#A!(*?Y:0PD^4#`%7A(0``B@8T`.,%`*#A!""@X;,PF.$``%/C`C0` -M$_^/#P.S,)@1@3^#$H.`B!``,*#CLH#8$90(".`($*#A_O__ZP!P4.)H```: -MN`&?Y?[__^L($*#A!2"@X:P!G^5`]/_K!1"@X00@H.$',*#A"`"@X?[__^N4 -M`9_E!Q"@X0<@H.$W]/_K!P"@X4T``.I\`9_E_O__ZP4`H.'^___KL#'8X0,` -M4.&`@(@B`*"@(P@``"J4``3@!`"@X?[__^L``%#C20``&@0`H.'^___K_O__ -MZT4``.H1,-CE!!"@X0``4^,,```*"`"8Y?[__^L$$*#A`)"@X04`H.'^___K -M``!9X00``!H(`*#A_O__ZQ\`6N,U``":!```Z@&@BN(<@(CB>J#OYB``6N/I -M__\:S#"?Y0"`H.,#D*#A6*"3Y2,``.JPMM/A_O__ZP$PB.(``%OA'0``&@H` -M6.&@()_EI`"?Y9@PGP6T1=,!ZCP(X[,PDN&7`P?@_O__ZP`PH.,$(*#A!0"@ -MX0<0H.'^___K!Q"@X04@H.%P`)_E\?/_ZP40H.$$(*#A`#"@XP<`H.'^___K -M`!"@XU0`G^4!(*#AZ//_ZP``H./^___K!P``ZG.`[^8*`%CAB#")X`4`H.$$ -M$*#A`0``B@\`6N/4__^:$#"?Y2I@AN(`(.#C!B&#Y_B/O>@``````````$Y! -M3D01$5-5``!350$`4./P3RWI`4"@X1303>("8*#A!0``"@<``#H"`%#C:0`` -M&K0AG^68()+E`D"!X*@AG^64()+E`D"$X*"QG^4&$(3@NB#;X;`!V^&0`@+@ -M`@!1X0"`H),#D*"1"*"@D54``)I8``#J`1"@XP0`H.'^___K"%#;Y040H.$` -M<*#A!`"@X?[__^L'`*#A<8#_Y@50:.!U4/_F!@!5X790_X;^___K`""@XPD0 -MH.%U,._F!P"@X0`@C>7^___KN!#;X0``4.,$`*#A`*#@$_[__^L`,*#C!!!A -MX`,@B^`!,(/B)RN"XNX@@N(`<-+E%""@X_\`5^.2!P?@+```"@<@B^"=+(+B -M%"""X@`@DN4!`%+A`P``&LPPG^4'<)/@`P``&B(``.H@`%/CZO__&A\``.H$ -M,)?E``!3XQP```H),*#A`,"@XPB0C>4$D*#A#*"-Y0-`H.$&H*#A#&"@X0T` -M`.H$()?E`<"@XQPH$N`$```*$!"7Y0(LH.,$`*#AF!(AX/[__^L!8(;B`8"( -MX@),A.)V8/_F>(#_Y@4`5N'O__\Z"4"@X0I@H.$(D)WE#*"=Y05`A."%E(G@ -M!F!EX```5N.H__\:"H"@X0```.H`@.#C_O__ZP@`H.$4T(WB\(^]Z``````` -M````%)T``/!!+>D),-#E`$"@X0``4^/P@;T(`%"@XUAPG^4!8*#C"@``Z@0` -ME.46!1#@!0``&@`0E.4!(*#C$#"4Y0$0A>"%-(/@_O__ZP%0A>)U4/_FN##7 -MX04`4^'Q__^*``"4Y0$@H.,0$)3E_O__ZP0`H.'P0;WH&OO_Z@````#X3RWI -M@#2?Y0!PH.$`0*#CNX080H.'^___K;#2?Y0<08>```-/E`2"$X@``4.,# -M```*"0`3Y0$`4.$!4*`#S0``"G)`_^84,(/B(`!4X_/__QH`0*#C+!2?Y00P -MH.$#(('@`0"$XITL@N(4,(/B'2""X@!0TN4``%7CO@``"G!`_^8@`%3C]/__ -M&@`@H./T$Y_E`N"@X0)0H.$"0*#A`C"@X12`H.,"P('@"@@0`PH.,!((+B(`!2X][__QH$`%/A`T"@@0Y0H)$!@(3B>(#_ -MY@,`6.,V``":/*.?Y0!@H.,4L*#C!9"*X`D``.H&,-/EFZ,CX)T\@^(4,(/B -M``"3Y63W_^L!,(;B``!0XP8``!IS8._F!C")X`0`5N$G.X/BZ#"#XO#__SH3 -M``#J!5"&X.0RG^4$0&;@"&!FX'50X^;`! -M`(3BG2R"XA0P@^(=((+B`"#2Y0``4N-#```*<$#_YB``5./T__\:/P``ZI[$ -M(>`#`(S@G0R`X@%0@N(<`(#B%#"#XIT<@>(8$('B``#0Y000T>4!`%#A`D"@ -M,74@_^8@`%+C\/__&M`AG^4`8*#C!H""X"<[B.+N,(/B`##3Y00`4^$E```: -M)UN(XJRAG^6PL9_EZ8"%XA20H./H4(7B!C#8Y?\`4^.9HR/@$@``"@8`U>6= -M/(/B%#"#XK@0VN&9``#@`""3Y0`PBN```(O@G3R#XA0P@^(`,)/E`S"!X`(` -M4^$$```:$O__ZP8PU>7_`%/CZ?__&@L``.I(,9_E%`"@XP!0H.,#8(;@-#&? -MY08@UN60,B#@!O__ZP,``.H!8(;B(`!6X]#__QH`4*#C%("@XPRQG^4`H9_E -M`3"@XY@$">`'`*#A"6"+X`DPQN6X$-KA_O__ZP``5>,'$&'@"1"+YR0``!H% -M,*#A!2"*X`$`@^(G*X+B`5"%XNX@@N(`(-+E_P!2XYBB(N`7```*G2R"XA0@ -M@N(`()+E`0!2X0\``)J4P)_E'R"@XP%00N("((S@)PN"XG4@_^8`$*#A`5"" -MXN@`@.+I$('B!@#0Y750_^8#`%7A!@#!Y?+__XH"``#J<##_YB``4^/>__\: -M5""?Y0(P@^`&0,/E/`"?Y0`PH.,#((#@",#6Y9TL@N(4,(/B'"""X@`0TN4! -M`%SA`1!!X@`0PC4*#5/C]/__&A\PH.,&`*#A"##&Y?B/O>@`````'9T``!2= -M``#HG```\$\MZ;!1G^6DT$WBN!#5X;H`U>'^___K<`#_Y@!#H.$$`*#A_O__ -MZP`04.(0$(WE7P``"@`PX.,$(*#A_Q"@XU0PA>58,(7E`("@X_[__^L/<*#C -M!4"@X0B@H.&^-]7A``!3XTP```JZ(-3A!Y"@X;JPU.$%8*#A6!"4Y9,"`N`0 -M,)WE`0!QXUAPA`4".H/B'#"-Y;@PU.$+L&/@&""-Y7NP_^8W``#J'P!8XS@` -M`(H8$)WE(""-X@"@C>4!$(7@%!"-Y10PG>4*$*#A`@"#X@0PH./^___K``!0 -MXR8``!JP$MWA_S\/XP,`4>%44(0%(0``"K!SW>$04)WEL#3=X;`EW>$'>('A -M`!"5Y0$`<>,3```:`CB3X0\```H'`*#A##"-Y8[^_^L,,)WE`8"(X@H@H.%X -M@/_F`!"@X10`G>4$,('EOC?6X;PPP>$(,-3E`*"-Y1`0D>7^___K`'"%Y04` -M`.H'`%'A!%"%X@(```H<$)WE`0!5X>+__QJX,-3A"[!CX'NP_^9[4+_F``!5 -MX\3__ZH)<*#A!E"@X0%P1^("4$7B`0!WXZO__QH0`)WE_O__ZZ30C>+PC[WH -M`````/@RG^7L+`CC\$\MZ0`0H..RH)/AW"P`XT7?3>(`0*#CLA"#X20=">.Z -M(-/A`W"@X0Q`C>40@(WB`6"3YP10H.'_D.#C_[\/XYH""N`+``#J`%"-Y?[_ -M_^L``%#C`"#@$PP@C14#```:$1Z-XKDPD>$+`%/A"```"K@PU^$#0(3@NL#7 -MX0H`A.`%$*#A"""@X0P`5.$!,*#C[/__.F`"G^4$$*#A5%*?Y?[__^O:C`#C -M``!4XW1P_^:X<(7A@P``"K@`U>$&$*#A$""-X@@PH.,*H&#@`,"@XP0`BN`` -MP(WE_O__ZP``4.-U```:_S#@XQ$NC>*S,)+A/0M3XVT``!JV(-;AMC#5X0,` -M4N%F```:LB'6X;(QU>$#`%+A8@``&@@@EN4(,)7E`P!2X5X``!H&$*#A!0"@ -MX0$JH.,`0*#C_O__Z[!AU>&X<(7A$)"-X@$)5N.D49_E?V^&DB!@H(,#8(:2 -MUGP`XYBAG^4$L*#AIF2@D1$``.JTX-#ANL#5X;<`E>&,3,CE`+"-Y9#L(.#^ -M___K``!0XP(``!JP,=WA!`!3X00```H$$*#A6`&?Y?[__^O^___K1P``Z@%` -MA.(&#(3B`C"@XP0`@.(&`%3A!("%X`05BN`)(*#AD%,@X.3__SK^___K`0!P -MXP!0H.$$```:%`&?Y?[__^O^___K!0"@X3L``.H&`%3A)@``&A!`C>(`$*#C -M!`"@X8`@H./^___KU#"?Y0"`H.,#4*#A#GV#XKI@T^&1,-7E!A"@X0``4^,& +MG^4!(*#CM"'#X7"`O>@`````=@4```PQG^7P3RWI`&"@X;B`T^&$T$WB_`"? +MY0)0H.$!H*#ANG#3X0V0H.'^___KB+2@X3$``.K^___KW#"?Y0<0H.$!4$7B +M=5#_Y@!`H.$&`*#A#B#4Y0,P@N&P,,WAO##4X;`QS>'^___K!Q"@X;`"S>$( +M`)3E_O__ZP<0H.&P`\WA``"4Y?[__^L'$*#A`#"@X[`US>&P!,WA!@"@X?[_ +M_^L(8(;@`0"@X0@0H.'^___K"A"@X0T@H.$`,*#CL#?-X0`P5>(!,*`3"Z"* +MX+`&S>$``)3E_O__ZP`PE.4(,(/@`#"$Y?[__^L,`)3H`P!2X0$``!H$`*#A +M_O__ZP``5>,&`*#ARO__&@4`H.&$T(WB\(^]Z````````%-5`/+__T`BG^7X +M3RWI/#*?Y;I`TN$`8*#CJ%"3Y0$`=>,$```:`6"&X@0P@^(*`%;C^/__&OB/ +MO>@0,I_E!'"@X02"G^6D,)/E`P!5X2$``(H&-`#C!0"@X00@H.&S,)CA``!3 +MXP(T`!/_CP\#LS"8$8$_@Q*#@(@0`#"@X[*`V!&4"`C@"!"@X?[__^L`<%#B +M:```&K@!G^7^___K"!"@X04@H.&L`9_E5?3_ZP40H.$$(*#A!S"@X0@`H.'^ +M___KE`&?Y0<0H.$'(*#A3/3_ZP<`H.%-``#J?`&?Y?[__^L%`*#A_O__Z[`Q +MV.$#`%#A@("((@"@H",(```JE``$X`0`H.'^___K``!0XTD``!H$`*#A_O__ +MZ_[__^M%``#J$3#8Y000H.$``%/C#```"@@`F.7^___K!!"@X0"0H.$%`*#A +M_O__ZP``6>$$```:"`"@X?[__^L?`%KC-0``F@0``.H!H(KB'("(XGJ@[^8@ +M`%KCZ?__&LPPG^4`@*#C`Y"@X5B@D^4C``#JL+;3X?[__^L!,(CB``!;X1T` +M`!H*`%CAH""?Y:0`G^68,)\%M$73`>H\"..S,)+AEP,'X/[__^L`,*#C!""@ +MX04`H.$'$*#A_O__ZP<0H.$%(*#A<`"?Y0;T_^L%$*#A!""@X0`PH.,'`*#A +M_O__ZP`0H.-4`)_E`2"@X?WS_^L``*#C_O__ZP<``.IS@._F"@!8X8@PB>`% +M`*#A!!"@X0$``(H/`%KCU/__FA`PG^4J8(;B`"#@XP8A@^?XC[WH```````` +M``!.04Y$$1%350``4U4!`%#C\$\MZ0%`H.$4T$WB`F"@X04```H'```Z`@!0 +MXVD``!JT(9_EF""2Y0)`@>"H(9_EE""2Y0)`A."@L9_E!A"$X+H@V^&P`=OA +MD`("X`(`4>$`@*"3`Y"@D0B@H)%5``":6```Z@$0H.,$`*#A_O__ZPA0V^4% +M$*#A`'"@X00`H.'^___K!P"@X7&`_^8%4&C@=5#_Y@8`5>%V4/^&_O__ZP`@ +MH.,)$*#A=3#OY@<`H.$`((WE_O__Z[@0V^$``%#C!`"@X0"@X!/^___K`#"@ +MXP008>`#((O@`3"#XB4#0*#A!J"@X0Q@ +MH.$-``#J!""7Y0'`H.,<*!+@!```"A`0E^4"+*#C!`"@X9@2(>#^___K`6"& +MX@&`B.("3(3B=F#_YGB`_^8%`%;A[___.@E`H.$*8*#A")"=Y0R@G>4%0(3@ +MA92)X`9@9>```%;CJ/__&@J`H.$```#J`(#@X_[__^L(`*#A%-"-XO"/O>@` +M`````````!2=``#P02WI"3#0Y0!`H.$``%/C\(&]"`!0H.-8<)_E`6"@XPH` +M`.H$`)3E%@40X`4``!H`$)3E`2"@XQ`PE.4!$(7@A32#X/[__^L!4(7B=5#_ +MYK@PU^$%`%/A\?__B@``E.4!(*#C$!"4Y?[__^L$`*#A\$&]Z!G[_^H````` +M^$\MZ8`TG^4`<*#A`$"@X[A@T^$&$*#A_O__ZVPTG^4'$&'@``#3Y0$@A.(` +M`%#C`P``"@D`$^4!`%#A`5"@`\T```IR0/_F%#"#XB``5./S__\:`$"@XRP4 +MG^4$,*#A`R"!X`$`A.*=+(+B%#"#XAT@@N(`4-+E``!5X[X```IP0/_F(`!4 +MX_3__QH`(*#C]!.?Y0+@H.$"4*#A`D"@X0(PH.$4@*#C`L"!X'*@[^8G"XSB +M`,"@X>X`@.+OP(SB`,#__\:!`!3X0-`H($.4*"1`8"$ +MXGB`_^8#`%CC-@``FCRCG^4`8*#C%+"@XP60BN`)``#J!C#3Y9NC(^"=/(/B +M%#"#X@``D^5?]__K`3"&X@``4.,&```:`$`%;A)SN#XN@P@^+P +M__\Z$P``Z@50AN#D,I_E!$!FX`A@9N!U4./FW**?Y2=;A>)T0/_F=F#_YNA0 +MA>(4@*#C!```Z@8`U>4!0$3B=$#_YIB@(.!H___K``!4X_C__QH+``#JI#*? +MY12`H..88I_E`U"%X`8`U>4!0$3B=$#_YIA@(.!<___K``!4X_C__QH'``#J +M`P!6XP4``(H`,*#C7,*?Y0,@H.$#0*#A%."@XPX``.H`,*#C1!*?Y0-`H.$# +M(('@`0"$XITL@N(4,(/B'2""X@`@TN4``%+C0P``"G!`_^8@`%3C]/__&C\` +M`.J>Q"'@`P",X)T,@.(!4(+B'`"`XA0P@^*='('B&!"!X@``T.4$$-'E`0!0 +MX0)`H#%U(/_F(`!2X_#__QK0(9_E`&"@XP:`@N`G.XCB[C"#X@`PT^4$`%/A +M)0``&B=;B.*LH9_EL+&?Y>F`A>(4D*#CZ%"%X@8PV.7_`%/CF:,CX!(```H& +M`-7EG3R#XA0P@^*X$-KAF0``X``@D^4`,(K@``"+X)T\@^(4,(/B`#"3Y0,P +M@>`"`%/A!```&A+__^L&,-7E_P!3X^G__QH+``#J2#&?Y10`H.,`4*#C`V"& +MX#0QG^4&(-;ED#(@X`;__^L#``#J`6"&XB``5N/0__\:`%"@XQ2`H.,,L9_E +M`*&?Y0$PH..8!`G@!P"@X0E@B^`),,;EN!#:X?[__^L``%7C!Q!AX`D0B^+N((+B`"#2Y?\`4N.8HB+@%P``"ITL +M@N(4((+B`""2Y0$`4N$/``":E,"?Y1\@H.,!4$+B`B",X"<+@N)U(/_F`!"@ +MX0%0@N+H`(#BZ1"!X@8`T.5U4/_F`P!5X08`P>7R__^*`@``ZG`P_^8@`%/C +MWO__&E0@G^4",(/@!D##Y3P`G^4`,*#C`R"`X`C`UN6=+(+B%#"#XAP@@N(` +M$-+E`0!(`$,(U"@U3X_3__QH?,*#C!@"@X0@PQN7XC[WH`````!V= +M```4G0``Z)P``/!/+>FP49_EI-!-XK@0U>&Z`-7A_O__ZW``_^8`0Z#A!`"@ +MX?[__^L`$%#B$!"-Y5\```H`,.#C!""@X?\0H.-4,(7E6#"%Y0"`H./^___K +M#W"@XP5`H.$(H*#AOC?5X0``4^-,```*NB#4X0>0H.&ZL-3A!6"@X5@0E.63 +M`@+@$#"=Y0$`<>-8<(0%`CJ#XAPPC>6X,-3A"[!CX!@@C>5[L/_F-P``ZA\` +M6.,X``"*&!"=Y2`@C>(`H(WE`1"%X!00C>44,)WE"A"@X0(`@^($,*#C_O__ +MZP``4.,F```:L!+=X?\_#^,#`%'A5%"$!2$```JP<]WA$%"=Y;`TW>&P)=WA +M!WB!X0`0E>4!`''C$P``&@(XD^$/```*!P"@X0PPC>6._O_K##"=Y0&`B.(* +M(*#A>(#_Y@`0H.$4`)WE!#"!Y;XWUN&\,,'A"##4Y0"@C>40$)'E_O__ZP!P +MA>4%``#J!P!1X010A>("```*'!"=Y0$`5>'B__\:N##4X0NP8^![L/_F>U"_ +MY@``5>/$__^J"7"@X090H.$!<$?B`E!%X@$`=^.K__\:$`"=Y?[__^NDT(WB +M\(^]Z`````#P,I_E["P(X_!/+>D`$*#CLI"3X=PL`.,`8*#C@]]-XK(0@^$D +M'0GCNB#3X0-PH.$&0*#A`5"3YPB@C>(&@*#AM+*?Y9D"">`+``#J`("-Y?[_ +M_^L``%#C`&#@$P0``!J"+XWB_Q\/X[LPDN$!`%/A"```"K@PU^$#0(3@NL#7 +MX0D`A.`($*#A"B"@X0P`5.$!,*#C[/__.F`"G^4$$*#A4'*?Y?[__^O:K`#C +M``!4XW2`_^:Z@(?A@P``"K@`U^$%$*#A"""-X@@PH.,)D&#@`,"@XP0`B>`` +MP(WE_O__ZP``4.-U```:##*?Y8(OC>*S,)+A/0M3XVT``!JV(-7AMC#7X0,` +M4N%F```:LB'5X;(QU^$#`%+A8@``&@@@E>4(,)?E`P!2X5X``!H'`*#A!1"@ +MX0$JH.,`0*#C_O__Z[`QU^&Z@(?A"+"-X@$)4^.@49_E?W^#DB!PH(,#<(>2 +MUJP`XYB1G^6G=*"1$@``ZK3@T.&ZP-7AN@"5X8Q,R.4`@*#C`("-Y9#L(.#^ +M___K"`!0X0(``!JX,-WA!`!3X00```H$$*#A6`&?Y?[__^O^___K1@``Z@%` +MA.(&#(3B`C"@XP0`@.('`%3A!("%X`05B>`+(*#AD%,@X./__SK^___K`0!P +MXP!0H.$$```:%`&?Y?[__^O^___K!0"@X3H``.H'`%3A)@``&@A`C>(`$*#C +M!`"@X8`@H./^___KT#"?Y0"`H.,#4*#A#GV#XKI@T^&1,-7E!A"@X0``4^,& M```*B`"5Y?[__^L&$*#AL`#$X8``E>7^___KL@#$X9&`Q>4<4(7B!P!5X01` -MA.+O__\:&>__ZQ``C>(`$*#C(""@XT?Z_^ML()_EW#P`XP$0H..S$(+A[.[_ -MZ^;^_^L``*#C$@``ZF``G^7^___K!0``ZE@`G^7^___K!0``ZE``G^7^___K -M!```Z@P@G>4!`'+C`0``"@``X.,$``#J%""?Y=H\`.,``.#C`!"@X[,0@N%% -MWXWB\(^]Z`````"H!0``W@P``-4%```'!@``,08``%X&``")!@``\$\MZ130 -M3>(!`%#C`E"@X0`PC>4`(*#CD#.?Y0%`H.$4),/E!0``"@<``#H"`%#CV0`` -M&G@SG^68,)/E`T"!X&PSG^64,)/E`T"$X&`SG^64,)/E`P!4X<\``#I48Y_E -M!2"$X+HPUN&P$=;AD0,#X`,`4N'(``"*=1#_Y@0`H.'^___KNA#6X00`H.'^ -M___K"'#6Y0<0H.&X`L;A!`"@X?[__^MQL/_F``!;XP5@H`$`H)T%&P``"@0` -MH.$'D&O@;_W_ZP4`6>$%D*`A`!"=Y7F0_^8)0(3@!6!IX(FDH.$*(*#A"J"! +MA.+O__\:&>__ZP@`C>(`$*#C(""@XT?Z_^MH()_EW#P`XP$0H..S$(+A[.[_ +MZ^?^_^L``*#C$0``ZF``G^7^___K!0``ZE@`G^7^___K!```ZE``G^7^___K +M`P``Z@$`=N,!```*``#@XP0``.H4()_EVCP`XP``X.,`@*#CLX""X8/?C>+P +MC[WH``````#^__^=!0``W@P``,H%``#\!0``)@8``%,&``!^!@``\$\MZ1S0 +M3>(!`%#C`E"@X00PC>4`(*#CG#.?Y0%`H.$8),/E!0``"@<``#H"`%#CW``` +M&H0SG^68,)/E`T"!X'@SG^64,)/E`T"$X&PSG^64,)/E`P!4X=(``#I@8Y_E +M!2"$X+HPUN&P$=;AD0,#X`,`4N'+``"*=1#_Y@0`H.'^___KNA#6X00`H.'^ +M___K"'#6Y0<0H.&X`L;A!`"@X?[__^MQL/_F``!;XP5@H`$$H)T%&P``"@0` +MH.$'D&O@$%D*`A!!"=Y7F0_^8)0(3@!6!IX(FDH.$*(*#A"J"! MX`"`H.$0`)#EBP2`X/[__^L`(.#C!#"8Y1``5>,2F>#A&;N#X02PB.4"``": -M"`"@X3K]_^L!``#J"`"@X8/W_^N((I_E$#T)XP,`DN<``%#C````"GWW_^L` -M,.#C`("@XX4,,(WE!9"@X5"RG^54``#J#P!9XP(` -M`)JX$-OA`#"@XQ8``.H$`*#A`?7_ZP`P4.+X__\:"""@X0`0G>4$`)WE`X"@ -MX?[__^L$`*#A-OW_ZP@@G>4*$*#A`%"@X1``D.7^___K#""=Y00PE>4%`*#A -M`C"#X00PA>58]__K-```Z@,@B^`!,$/BG2R"X@T@@N(``-+E%""@X_\`4..2 -M``#@"@``"@`@B^"=+(+B%"""X@`@DN4"(('@!`!2X0,``!J<,9_E``"#X/C\ -M_^L!``#J'P!SX^G__QH$`*#AN!#;X?[__^M\,9_E``"@XP008>``P-/E`2"` -MX@``7.,"```*"<`3Y0$`7.$$```*<@#_YA0P@^(@`%#C]/__&@,``.H\,9_E -M%""@XY(P(.`8^/_K!""=Y0$PB.(``%CC!""@`7.`_^8$((WE`""=Y0H@H`$` -M((WE"#"=Y0=`A.`&8&?@`Z"*X`<`5N&H__\J!`"=Y0@@H.$`$)WE_O__ZP`` -M5N,P```*!Q"@X00`H.'^___KR#"?Y00`H.$`4*#C<7#_YK@0T^'^___KN#"? -MY0008>```-/E`2"%X@``4.,"```*"0`3Y0$`4.$#```*C0O`P````` -M```````4G0``'9T``/=/+>D#L*#A6#&?Y0%PH.$$`(WE`0"@X0)0H.$6H-/E -M"A"@X?[__^L``%7C!7"@`7%@_^9(```*"@!5X08``)H$`)WE!Q"@X04@H.$+ -M,*#A#-"-XO!/O>C^___J`)"@XP1!G^4)@*#A!R!FX`DPU.4!$(CB``!3XPL` -M``H``)3E`@!0X0@``!H0$)3E"P"@X84DH.&&%('@_O__ZQ``6.,`<*`3'0`` -M&@D``.H(`-3E%$"$X@``4.,!```*``!3XP```!H(D*#A<8#_YA``6./E__\: -M%!"@XXPPG^4'<&;@"B"@X9$)">`$`)WE!Q"@X0E`@^`)<(/G$#"4Y?[__^L0 -M$)3EA22@X884@>``<*#A"P"@X?[__^L!,*#C"3#$Y4@`G^4`,*#C`R"`X`C` -MU.6?+(+B%#"#XIP@@N(`$-+E`0!(`$,(U!0U3X_3__QH/,*#C"##$ -MY0<`H.$,T(WB\(^]Z`````"4GP```````"C!G^4!`%#C\$#T,)_EE#"3Y0-`A.#L -M,)_E!2"$X+`1T^&Z,-/AD0,#X`,`4N$Q``"*!`"@X0<0H.'^___K"H"@X7%@ -M_^8``%;C#0``"@=@9N`$$*#A``"@XPHPH.%V8/_F!0!6X75@_X8&(*#A!D"$ -MX/[__^N&A(K@!5!FX`!@4.(`8.`3`#"@XP$``.IR,/_F!5!GX`<`5>$!((/B -M^O__*@``4^,*```*EP,'X`00H.$(,*#A``"@XW=P_^8'(*#A!T"$X/[__^N' -MA(C@``!0XP!@X!,``%7C!P``"@00H.%U(/_F"#"@X0``H./^___K``!0XP`` -M``H`8.#C!@"@X?"'O>@``````````"`QG^4`(*#C\$`!*Z#C!`!3X0``B."84)_EZO__BM9,`.,`,*#CM#"%X5?Q -M_^L`8%#B'0``"K1@A>'8C`#C`$"@XPV@H.$*``#JN`#5X;K`U>&P0,WAD`0` -MX`%`A.)T0/_F<`#_YK0`Q^&X`(7AG`8@X/[__^NP`=7A!GR$X@1PA^($%8G@ -M?P^`X@T@H.$#`(#BAW"%X``PH.,4P)_EH`14X>C__[K0/(SES#R,Y8#0C>+P -MA[WH`````-X,``#P3RWI1*B?Y3@]">,`$.#C0=]-X@"0H..\%,KAP%"-X@-P -MFN<4,$/BOA3*X0I@H.$#0)KG*#"#XA0(G^4)@*#A`S":YU"0BN6ZL-KA'#"- -MY?[__^N^(-KA"1"@X00`H.$8D(WEHB&@X?[__^L)$*#A`2J@XP<`H.'^___K -ML"':X0D0H.$<`)WEP#"-XH(@H.$$,(/B/#"-Y?[__^L)$*#A(""@XV``BN+^ -M___K"1"@X4`@H.,%`*#A_O__ZY0'G^4)$*#A"2"@X;_N_^OL/`CCLU":X=P\ -M`..SD(KA`C"%X@%0A>*;`P/@FP4*X"`PC>4HH(WE!@$`ZK`@TN$"`%7A!@`` -M&L4BH.$!P*#C'P`%X@(1E.<<$('A`A&$YP4``.H!,(/B@R"&X`$`4^$C*X+B -M[B""XN___[KBS`CCO""6X0(`4^'K``"Z(."=Y0`0H.,H`)WE0""-X@@PH.,` -MX(WE_O__ZP``4.,P`(WEX0``&G6@_^:P&]WA"@"@X?[__^NP)-WA_SP"XO$, -M4^-/```:_S`"XK`5W>$/D*#C"0!HX`,X@>$K``#JP!"-X@DAD><"`%/A)@`` -MFL`@G>4`(%+B`2"@$Q``6.,!(((#``!2XP&`B`)X@/\&`P``"K`&UN$4,(WE -M$O#_ZQ0PG>7`((WB9!:?Y0@`@N(\()WE"0&`X`,``.H$P!+ELN!1X0C``N6T -MX$'A!"""X@(0@>(``%+A]___&@$+%(J#A"0&!X(D0AN`!P*#C0#``Y1\` -M!>*PIL'A`A&4YQP0@>$"$83G`@``Z@&02>(``%GAT?__R@``6>,(``"JQ3*@ -MX0'`H.,?$`7B"@"@X0,AE.<<(8+A`R&$Y^KO_^N:``#J#R!HX@(`6>&7``#* -M`$!@(CB0#`)Y0$`H.,",93G'Q`%XGB`_^80 -M,8/A`C&$YXD``.KR#%/C;P``&K`1UN'_(`+BL#;=X;`%W>$!`%/A.!"6Y0(( -M@.$D`(WE`1"`X#@0AN5\```J'`"=Y8/@H.$LX(WEOI"0X0``6>,(```:Q3*@ -MX0$`H.,?$`7B`R&4YQ`A@N$#(83G'!"=Y;Z@@>%M``#J&"6?Y0L0H.&4`)+E -M%#"-Y?[__^L4,)WE``!3X64``#H@P)WE0""-XK#GW>$%,*#C,!"=Y0#`C>6P -MR-WAFPD`X#3@C>4PP(WE_O__ZT`0W>6P)=WA.#"6Y0$H@N$DX)WE`@!3X0,P -M8H`X,(:%`@!>X;`GW9&P.-V1$P``FJG"H.'%`J#A'Q`)X@P`C>4?(`7B`0"@ -MXS@@C>4,X93G-""=Y1#ASN$P,)WE#.&$YPP0G>4XX)WE`<&4YQ`.C.$!`83G -M'!"=Y2P`G>6PH('A`@"'X@`0H..PP-#A#`!9X04``!H!"U'C`1&@X;$@A^&P -M,,#A!```*B\``.H!$('B!`"`X@$+4>/R__\:!Q"@X0$*A^*RP-'A_^,`XQB@ -MG>4$$('B#@!:X0``7),'```:`0"*X@K!H.$*$8?@O""'X7``_^88`(WELC#! -MX1H``.H``%'A[O__&A<``.KU#%/C%0``&L4"H.$!$*#CL)7=X?\@`N(`P93G -M'^`%X@(HB>$1SHSA`,&$YU`PEN4"`%/A"0``BKS$UN&^,-;A#`!3X:PRH($? -MP`R"`P&4AQ$4+`(#@*`"-Y0L0 -M@>`@$(WEOC#6X0,`5>'B+`BS`#"@L[(0EK']_O^Z_`"=Y<`@C>(4$Y_E#C"@ -MXUP`@>4X`)+E/!"2Y00@0N(!`(#B`0!0X0X```KP4I_E`V"@X8-0A>!@4(7B -M!0``ZK(P5>```%/B"```"BWO_^L`,*#CLC#%X0``5N,!8$;B]O__J@$``.H! -M,%/BZ/__*JPBG^6P-M+A``!3XQ8``!JP%M+A`B""X@``4>,/```*C"*?Y0,0 -MH.&#,(+@8"""XF`P@^(#``#JLJ!3X0#`H..RH$+ALL!#X0\`4>,",(/B`1"! -MX@(@@N+V___:`@``Z@$P@^(0`%/CZ/__&@"@H.,'4*#A.(*?Y4"0C>(*8*#A -M*@``ZK(`U>&ZX-CA`0"`XKC`V.$`8(WEG@``X```;.#^___KL`3=X080H.$) -M(*#A_PP`X@,PH./R#%#CL&#%`;)@Q0$7```*L,#5X;H`V.$`8(WEG```X/[_ -M_^NP--WAL+;=X?\\`^+R#%/C"@``&K+`U>$#,*#CN@#8X080H.$)(*#A`&"- -MY9P``.#^___KL#;=X0L`4^$"```*`."@X[#@Q>&RX,7A`:"*X@10A>(8`)WE -M!A"@X0D@H.$!,*#C``!:X6@!G^7-__^Z`V"@X>P\".,`H*#A`("@X[-0D.$& -M4(7@)```ZL4RH.$#,93G`0!SXQ]0A0,!4(4"'```"@``5>,?`(7B!0"@H7XQ -M%>(!,$-"P`*@X8,]X$$`$93GHSW@00$P@T(6(Q'@#0``&@(``.J\P)?A!0!< -MX0D```H8X)WE`L&@X0X`4N$!((+B]___NA8S@>$`,83G=0#_Y@&`B.*K[O_K -M`5"%XA\`%>/B__\:!`!8XP(``(J^,-KA`P!5X=?__[H<`)WE`5"@X\?]_^L' -M`*#A`2N@XP00H.%*]O_KB#"?Y>PL".,#<*#ALF"3X05@AN`6``#JQC*@X0,Q -ME.!!`B&4YZ,]X$$!,(-"%2,2X````!J![O_K'P`6X^[__QJ^,-?A -M`P!6X>7__[K.^O_K``"@XT'?C>+PC[WH`````+`&```B(E-58@````````!P -M0"WI\$"?Y0!0H.-"/J#C`&"@X;8PQ.$`4,3E`5#$Y?[__^O4,)_E!@"@X154 -MP^445,/E_O__ZP4`4.$`4.`3%P``&O[__^NQZ__K``!0XPH```JH()_E0AZ@ -MXZ0`G^7^___KMA#4X9P`G^7^___KF`"?Y?[__^L``.#C<("]Z/[__^L``%#C -M`0``"L+]_^O^___K8#"?Y0!0H.,!(*#C`"##Y5!`G^5"'J#C4""?Y5``G^7^ -M___K7!"4Y5``G^7^___K!C0`XT@`G^6S$)3A_O__Z[`1U.$\`)_E_O__Z[(1 -MU.$T`)_E_O__ZP$`H./^___K!0"@X7"`O>@`````T+P,`.$&``#`!@``Z08` -M``<'```=!P``,`<``$8'``#(`0```0````````"PL+"`1````+"PL("<```` -MKP>Q@'P!``"PL*J`W`$``+"PL(#L`0``L+"L@%@"``"PL+"`7`(``+"PL(!D -M`@``L+"P@&P"``"PL+"`=`(``+"PL(!X`@``L+"P@.`"``"PL+"`)`,``+"P -MJX"<`P``L*\&@(0$``"L`[&`D`4``*\_!(!\!@``L+"P@(0&``"PL+"`D`8` -M`+"PKH`@!P``L+"P@&@'``"PL*J`\`<``+"PJH`L"```L+"J@%`)``"PKP2` -M=`H``*\_"(#(#@``KR*R@&00``!?A""`X!$``+"PJ(`D$@``L+"L@!@4``"O -M"+&`,!4``+"O!("@%@``KP&Q@,P7``"PL*B`8!@``+"O(H!@&0``L*\H@!P< -M``!?A"*`=!T``+"PK(#('0``L*\D@*P?``"PL*Z`Z"```+"PK("$(0``L*\B -M@$PB``"O/P:`O"8``+"PKH#,)P``L+"J@$`I``"PK!^`E"H``+"PK(`H+0`` -MJ@.Q@*0M``"PL*B`Y"T``+"PJ(!(+@``L+"N@.PN``"PL*J`3"\``*H#L8#, -M+P``L*P?@%@Q``"PKR:`Z#,``+"O#("\-P``L+"L@&`X``"PL*R`W#@``+"N -M"8`H.P``L+"J@``\``"PKR"`'#T``*\(L8!X/P``L*\$@&1!``"PL*R`X$$` -M`*\(L8!\1@``L*\H@#Q(``"O/P2`7$L``+"O!(`@3P``KP>Q@)10``"PL*Z` -MS%$``+"N'X#\4@``KS\`@&!;``"PL*J`1E1,(%9E"5X+#!X)7@L -M,'@E>"PP>"5X+#!X)7@L,'@E>"PP>"5X+#!X)7@*`#PU/G-P87)E6S0J.%T@ -M)7@@+"!P1G1L26YF;RT^`H`/#4^<$9T;$EN9F\M -M/F9T;%9E"`L($943%]615)324].(#T@)7@*`#PU/G!&=&Q);F9O+3YT -M;W1A;$QO9VEC0FQK("5X("P@<$9T;$EN9F\M/FUA>%!H>4)L:R`]("5X"@`\ -M-3YP0F%D0FQK26YF;RT^8VYT("5D"@`\-3Y'971"861";&M48FP@=&]O(&UA -M;GD@8F%D(&)L:PH`"!%`H`/#4^1FQA`H`/#4^97)R;W(Z1V5T -M4F5M87`@4$%"(&ES(#`@+$Q"02`]("5X("P@;F5W(%!"02`]("5X("P@)7@@ -M"@`\-3Y00D%,87-T('!B82`]("5D("`*`$9T;%-E=%-Y7-);F9O+G-Y"`*`$9T -M;$-A8VAE5W)I=&5"86-K"@`\-3Y&=&Q4:6UE2&]O:SI&=&Q#86-H941E;&%Y -M5W)I=&5!3$P*`#PU/F5X8VAA9V4@8FQO8VL@"Q$871E(#T@)7,*`#(P,3`Q,3@`3$]!1$52($943"!)3D9/.E9E`H`3F5E9"!U<&1A=&4@3&]A9&5R(2$A`#PU/D-A8VAE(%9E!``N!P`````````````!```` -M`0```&$````!``````````````!^9@``$@```````````````0````````!J -M`````P``<```````````D&8``"L```````````````$`````````$0````,` -M`````````````+MF``!Z```````````````!``````````$````"```````` -M``````"0:0``(!````X```"P````!````!`````)`````P`````````````` -ML'D```\&``````````````$```````````````````````````````$````` -M``````````0`\?\````````````````#``$``````````````````P`#```` -M``````````````,`!``'``````````````````$`"@```$`````````````! -M``````````````````,`!0`````````````````#``8`!P```$0````````` -M```!``H```"8`````````````0`'````G`````````````$`"@```'@!```` -M```````!``<```!\`0```````````0`*````V`$```````````$`!P```-P! -M```````````!``H```#H`0```````````0`-````[`$``&P````"``$`!P`` -M`.P!```````````!``H```!4`@```````````0`'````6`(```````````$` -M!P```%P"```````````!``<```!D`@```````````0`'````;`(````````` -M``$`!P```'0"```````````!``<```!X`@```````````0`*````V`(````` -M``````$`!P```.`"```````````!``H````<`P```````````0`'````)`,` -M``````````$`"@```)@#```````````!`!X```"<`P``Z`````(``0`'```` -MG`,```````````$`"@```(`$```````````!``<```"$!````````````0`* -M````C`4```````````$`!P```)`%```````````!``H```!P!@`````````` -M`0`'````?`8```````````$`!P```(0&```````````!``H```",!@`````` -M`````0`F````D`8``)`````"``$`!P```)`&```````````!``H````4!P`` -M`````````0`S````(`<``$@````"``$`!P```"`'```````````!``H```!@ -M!P```````````0`'````:`<```````````$`"@```.@'```````````!``<` -M``#P!P```````````0`*````*`@```````````$`!P```"P(```````````! -M``H````\"0```````````0`'````4`D```````````$`"@```&P*```````` -M```!`$4```!T"@``5`0```(``0`'````=`H```````````$`"@```)0.```` -M```````!`%(```#(#@``G`$```(``0`'````R`X```````````$`"@```%`0 -M```````````!`&````!D$```?`$```(``0`'````9!````````````$`"@`` -M`-01```````````!``<```#@$0```````````0`*````&!(```````````$` -M;0```"02``#T`0```@`!``<````D$@```````````0`*````R!,````````` -M``$`?@```!@4```8`0```@`!``<````8%````````````0`*````+!4````` -M``````$`DP```#`5``!P`0```@`!``<````P%0```````````0`*````G!8` -M``````````$`HP```*`6```L`0```@`!``<```"@%@```````````0`*```` -MR!<```````````$`N````,P7``"4`````@`!``<```#,%P```````````0`* -M````7!@```````````$`!P```&`8```````````!``H```!4&0`````````` -M`0`'````8!D```````````$`"@````P<```````````!``<````<'``````` -M`````0`*````;!T```````````$`!P```'0=```````````!``H```#$'0`` -M`````````0`'````R!T```````````$`"@```*`?```````````!``<```"L -M'P```````````0`*````W"````````````$`R0```.@@``"<`````@`!``<` -M``#H(````````````0`*````?"$```````````$`!P```(0A```````````! -M``H```!`(@```````````0`'````3"(```````````$`"@```)@F```````` -M```!``<```"\)@```````````0`*````Q"<```````````$`!P```,PG```` -M```````!``H````T*0```````````0`'````0"D```````````$`"@```'PJ -M```````````!`-8```"4*@``E`(```(``0`'````E"H```````````$`"@`` -M`!PM```````````!``<````H+0```````````0`*````F"T```````````$` -M!P```*0M```````````!``H```#@+0```````````0`'````Y"T````````` -M``$`"@```$`N```````````!`.0```!(+@``I`````(``0`'````2"X````` -M``````$`"@```.0N```````````!``<```#L+@```````````0`*````2"\` -M``````````$`!P```$PO```````````!``H```#`+P```````````0#T```` -MS"\``(P!```"``$`!P```,PO```````````!``H```!(,0```````````0`& -M`0``6#$``)`"```"``$`!P```%@Q```````````!``H```#8,P`````````` -M`0`9`0``Z#,``-0#```"``$`!P```.@S```````````!``H```"P-P`````` -M`````0`'````O#<```````````$`"@```%@X```````````!``<```!@.``` -M`````````0`*````V#@```````````$`!P```-PX```````````!``H````< -M.P```````````0`'````*#L```````````$`"@```/@[```````````!``<` -M````/````````````0`*````$#T```````````$`!P```!P]```````````! -M``H```!D/P```````````0`'````>#\```````````$`"@```%A!```````` -M```!`"D!``!D00``?`````(``0`'````9$$```````````$`"@```-Q!```` -M```````!`#8!``#@00``G`0```(``0`'````X$$```````````$`"@```&Q& -M```````````!`$,!``!\1@``P`$```(``0`'````?$8```````````$`"@`` -M`#A(```````````!``<````\2````````````0`*````/$L```````````$` -M!P```%Q+```````````!``H````,3P```````````0`'````($\````````` -M``$`"@```(A0```````````!``<```"44````````````0`*````Q%$````` -M``````$`5`$``,Q1```P`0```@`!``<```#,40```````````0`*````]%(` -M``````````$`80$``/Q2``!D"````@`!``<```#\4@```````````0`*```` -M3%L```````````$`!P```&!;```````````!``H```!<7````````````0`` -M```````````````#``@``````````````````P`)``H````````````````` -M`P!M`0``X,`,``0````!``0``````````````````P`*```````````````` -M``,`"P![`0```````$0````2``$`B0$`````````````$````*`!``!$```` -M6````!(``0"N`0`````````````0````O@$``)P```#@````$@`!`,X!```` -M`````````!````#<`0``?`$``&`````2``$`Z@$``-P!```0````$@`!`/P! -M`````````````!`````-`@``6`(```0````2``$`&`(``%P"```(````$@`! -M`"\"``!D`@``"````!(``0`[`@``;`(```@````2``$`2`(``'0"```$```` -M$@`!`&`"``!X`@``:````!(``0!O`@`````````````0````>@(``.`"``!$ -M````$@`!`(@"```D`P``>````!(``0":`@`````````````0````K`(``(0$ -M```,`0``$@`!`+X"``"0!0``[````!(``0#+`@`````````````0````T@(` -M`'P&```(````$@`!`.<"`````````````!````#W`@``A`8```P````2``$` -M#0,`````````````$````!@#`````````````!`````E`P``:`<``(@````2 -M``$`+`,``/`'```\````$@`!`#T#`````````````!````!'`P``+`@``"0! -M```2``$`4@,``%`)```D`0``$@`!`&`#`````````````!````!P`P`````` -M```````0````@@,`````````````$````(T#`````````````!````";`P`` -MX!$``$0````2``$`L@,`````````````$````,0#`````````````!````#, -M`P``8!@````!```2``$`V0,``&`9``"\`@``$@`!`.8#```<'```6`$``!(` -M`0#R`P``=!T``%0````2``$`_0,``,@=``#D`0``$@`!``P$``"L'P``/`$` -M`!(``0`5!```A"$``,@````2``$`(P0``$PB``!P!```$@`!`#4$``"\)@`` -M$`$``!(``0!*!```S"<``'0!```2``$`500``$`I``!4`0``$@`!`&@$```H -M+0``?````!(``0!Z!```I"T``$`````2``$`CP0``.0M``!D````$@`!`)L$ -M``#L+@``8````!(``0"N!```3"\``(`````2``$`MP0`````````````$``` -M`-`$`````````````!````#;!``````````````0````Y`0``+PW``"D```` -M$@`!`/$$``!@.```?````!(``0`#!0``W#@``$P"```2``$`%04``"@[``#8 -M````$@`!`!\%````/```'`$``!(``0`L!0``'#T``%P"```2``$`/04``'@_ -M``#L`0``$@`!`$@%`````````````!````!/!0``/$@``"`#```2``$`804` -M`%Q+``#$`P``$@`!`&H%```@3P``=`$``!(``0!U!0``E%```#@!```2``$` -M?04``&!;```D`0``$@`!`(4%`````````````!````"/!0```````!P````1 -M``@`FP4````````$````$0`#`*4%````````X"`!`!$`!`"N!0``X"`$```@ -M"``1``0`N`4``.`@`0````(`$0`$`,8%``#@0`P``(```!$`!`#8!0``Z,`, -M``0````1``0`Y@4``.`@`P````$`$0`$`.P%``#DP`P``0```!$`!`#\!0`` -MY<`,``$````1``0``&9T;"YC`"1A`"1D`$5X8VA086=E4F5M87!!9&0`1D9& -M4&%G90!&=&Q#86-H94EN:70`17AC:%!A9V5296UA<$EN:70`1V5T0F%D0FQK -M5&)L`$QO&-H0FQK4F5C;W9E5]P5=R:71E06QL0V%C:&5%;@!&=&Q'971#87!A -M8VET>0!G1FQA7-0F5R;P!&=&Q6 -M87));FET`$9T;#)&;&%S:%!R;V<`1FQA0!0=W)/ -M9F93879E4F5M87!48FP`1G1L0V%C:&575=R:71E`$9T;$-L -M;W-E`$9L87-H4V5T4F5A9%)E=')Y1&5F875L=`!F=&Q?;6%L;&]C`&9T;%]F -M&-H0FQK36%T8VA#;&]S90!%>&-H0FQK5W)I -M=&5-871C:`!73%)E<&QA8V4`1G1L5W)I=&5086=E`$9L87-H4F5F40,(WE!9"@X0`P9^)8LI_E%#"-Y54` +M`.H/`%GC`@``FK@0V^$`,*#C%@``Z@0`H.'[]/_K`#!0XOC__QH((*#A!!"= +MY0@`G>4#@*#A_O__ZP0`H.$U_?_K#""=Y0H0H.$`4*#A$`"0Y?[__^L0()WE +M!#"5Y04`H.$",(/A!#"%Y5;W_^LT``#J`R"+X`$P0^*=+(+B#2""X@``TN44 +M(*#C_P!0XY(``.`*```*`""+X)TL@N(4((+B`""2Y0(@@>`$`%+A`P``&J`Q +MG^4``(/@]_S_ZP$``.H?`'/CZ?__&@0`H.&X$-OA_O__ZX`QG^4``*#C!!!A +MX`#`T^4!((#B``!4$ +M()WE"B"@`00@C>4,,)WE!T"$X!0@G>4#H(K@`F"&X`<`5N&G__\J"`"=Y0@@ +MH.$$$)WE_O__ZP``5N,P```*!Q"@X00`H.'^___KR#"?Y00`H.$`4*#C<7#_ +MYK@0T^'^___KN#"?Y0008>```-/E`2"%X@``4.,"```*"0`3Y0$`4.$#```* +MC(W`P````````````4G0``'9T``/=/+>D#L*#A6#&?Y0%PH.$$`(WE +M`0"@X0)0H.$6H-/E"A"@X?[__^L``%7C!7"@`7%@_^9(```*"@!5X08``)H$ +M`)WE!Q"@X04@H.$+,*#A#-"-XO!/O>C^___J`)"@XP1!G^4)@*#A!R!FX`DP +MU.4!$(CB``!3XPL```H``)3E`@!0X0@``!H0$)3E"P"@X84DH.&&%('@_O__ +MZQ``6.,`<*`3'0``&@D``.H(`-3E%$"$X@``4.,!```*``!3XP```!H(D*#A +M<8#_YA``6./E__\:%!"@XXPPG^4'<&;@"B"@X9$)">`$`)WE!Q"@X0E`@^`) +M<(/G$#"4Y?[__^L0$)3EA22@X884@>``<*#A"P"@X?[__^L!,*#C"3#$Y4@` +MG^4`,*#C`R"`X`C`U.6?+(+B%#"#XIP@@N(`$-+E`0!(`$,(U!0U3 +MX_3__QH/,*#C"##$Y0<`H.$,T(WB\(^]Z`````"4GP```````"S!G^4!`%#C +M\$#X +M,)_EE#"3Y0-`A.#P,)_E!2"$X+`1T^&Z,-/AD0,#X`,`4N$R``"*!`"@X0<0 +MH.'^___K"H"@X7%@_^8``%;C#0``"@=@9N`$$*#A``"@XPHPH.%V8/_F!0!6 +MX75@_X8&(*#A!D"$X/[__^N&A(K@!5!FX`!@4.(`8.`3`#"@XP`@9^(!``#J +M<3#_Y@)0A>`'`%7A`1"#XOK__RH``%/C"@``"I<#!^`$$*#A"#"@X0``H.-W +MG4K`#C(!"@XX#03>(`D*#ANA"#X0)`H.',+(/E`V"@X=`L@^7T@)_E +M`7"@XPP``.K^___KI#*@X3,^@^(!((3B`C"#X@0`AN`?$`3B`S&&X(Q,P.5R +M0/_F!""3Y1K_ +M_XK63`#C`#"@X[0PA>%/\?_K`&!0XAT```JT8(7AV(P`XP!`H.,-H*#A"@`` +MZK@`U>&ZP-7AL$#-X9`$`.`!0(3B=$#_YG``_^:T`,?AN`"%X9P&(.#^___K +ML`'5X09\A.($<(?B!!6)X'\/@.(-(*#A`P"`XH=PA>``,*#C%,"?Y:`$5.'H +M__^ZT#R,Y]Z`````#>#```\$\MZ42HG^4X/0GC`!#@XT'? +M3>(`D*#CO!3*X(#<)KG%#!#XKX4RN$*8*#A`T":YR@P@^(4")_E"8"@ +MX0,PFN=0D(KENK#:X1PPC>7^___KOB#:X0D0H.$$`*#A&)"-Y:(AH.'^___K +M"1"@X0$JH.,'`*#A_O__Z[`AVN$)$*#A'`"=Y<`PC>*"(*#A!#"#XCPPC>7^ +M___K"1"@X2`@H.-@`(KB_O__ZPD0H.%`(*#C!0"@X?[__^N4!Y_E"1"@X0D@ +MH.'1[O_K[#P(X[-0FN'(!4(7BFP,#X)L%"N`@,(WE**"- +MY08!`.JP(-+A`@!5X08``!K%(J#A`<"@XQ\`!>("$93G'!"!X0(1A.<%``#J +M`3"#XH,@AN`!`%/A(RN"XNX@@N+O__^ZXLP(X[P@EN$"`%/AZP``NB#@G>4` +M$*#C*`"=Y4`@C>((,*#C`."-Y?[__^L``%#C,`"-Y>$``!IUH/_FL!O=X0H` +MH.'^___KL"3=X?\\`N+Q#%/C3P``&O\P`N*P%=WA#Y"@XPD`:.`#.('A*P`` +MZL`0C>()(9'G`@!3X28``)K`()WE`"!2X@$@H!,0`%CC`2""`P``4N,!@(@" +M>(#_!@,```JP!M;A%#"-Y0KP_^L4,)WEP""-XF06G^4(`(+B/""=Y0D!@.`# +M``#J!,`2Y;+@4>$(P`+EM.!!X00@@N("$('B``!2X??__QH!'(WBQ2*@X0D! +M@>")$(;@`<"@XT`P`.4?``7BL*;!X0(1E.<<$('A`A&$YP(``.H!D$GB``!9 +MX='__\H``%GC"```JL4RH.$!P*#C'Q`%X@H`H.$#(93G'"&"X0,AA.?B[__K +MF@``Z@\@:.("`%GAEP``R@',C>*)$(;@Q2*@X0F1C."PIL'A`8"(XD`P">4! +M`*#C`C&4YQ\0!>)X@/_F$#�(QA.>)``#J\@Q3XV\``!JP$=;A_R`"XK`V +MW>&P!=WA`0!3X3@0EN4""(#A)`"-Y0$0@.`X$(;E?```*AP`G>6#X*#A+."- +MY;Z0D.$``%GC"```&L4RH.$!`*#C'Q`%X@,AE.<0(8+A`R&$YQP0G>6^H('A +M;0``ZA@EG^4+$*#AE`"2Y10PC>7^___K%#"=Y0``4^%E```Z(,"=Y4`@C>*P +MY]WA!3"@XS`0G>4`P(WEL,C=X9L)`.`TX(WE,,"-Y?[__^M`$-WEL"7=X3@P +MEN4!*(+A)."=Y0(`4^$#,&*`.#"&A0(`7N&P)]V1L#C=D1,``)JIPJ#AQ0*@ +MX1\0">(,`(WE'R`%X@$`H.,X((WE#.&4YS0@G>40X<[A,#"=Y0SAA.<,$)WE +M.."=Y0'!E.<0#HSA`0&$YQP0G>4L`)WEL*"!X0(`A^(`$*#CL,#0X0P`6>$% +M```:`0M1XP$1H.&Q((?AL##`X00``"HO``#J`1"!X@0`@.(!"U'C\O__&@<0 +MH.$!"H?BLL#1X?_C`.,8H)WE!!"!X@X`6N$``%R3!P``&@$`BN(*P:#A"A&' +MX+P@A^%P`/_F&`"-Y;(PP>$:``#J``!1X>[__QH7``#J]0Q3XQ4``!K%`J#A +M`1"@X["5W>'_(`+B`,&4YQ_@!>("*(GA$(@$)WE"P"`X"@`C>4+$('@(!"-Y;XPUN$#`%7AXBP(LP`PH+.R$):Q_?[_ +MNOP`G>7`((WB%!.?Y0XPH.-<`('E.`"2Y3P0DN4$($+B`0"`X@$`4.$.```* +M\%*?Y0-@H.(7@8%"%X@4``.JR,%7@``!3X@@```HE[__K`#"@X[(PQ>$` +M`%;C`6!&XO;__ZH!``#J`3!3XNC__RJL(I_EL#;2X0``4^,6```:L!;2X0(@ +M@N(``%'C#P``"HPBG^4#$*#A@S""X&`@@N)@,(/B`P``ZK*@4^$`P*#CLJ!" +MX;+`0^$/`%'C`C"#X@$0@>("((+B]O__V@(``.H!,(/B$`!3X^C__QH`H*#C +M!U"@X3B"G^5`D(WB"F"@X2H``.JR`-7ANN#8X0$`@.*XP-CA`&"-Y9X``.`` +M`&S@_O__Z[`$W>$&$*#A"2"@X?\,`.(#,*#C\@Q0X[!@Q0&R8,4!%P``"K#` +MU>&Z`-CA`&"-Y9P``.#^___KL#3=X;"VW>'_/`/B\@Q3XPH``!JRP-7A`S"@ +MX[H`V.$&$*#A"2"@X0!@C>6<``#@_O__Z[`VW>$+`%/A`@``"@#@H..PX,7A +MLN#%X0&@BN($4(7B&`"=Y080H.$)(*#A`3"@XP``6N%H`9_ES?__N@-@H.'L +M/`CC`*"@X0"`H..S4)#A!E"%X"0``.K%,J#A`S&4YP$`<^,?4(4#`5"%`AP` +M``H``%7C'P"%X@4`H*%^,17B`3!#0L`"H.&#/>!!`!&4YZ,]X$$!,(-"%B,1 +MX`T``!H"``#JO,"7X04`7.$)```*&."=Y0+!H.$.`%+A`2""XO?__[H6,X'A +M`#&$YW4`_^8!@(CBH^[_ZP%0A>(?`!7CXO__&@0`6.,"``"*OC#:X0,`5>'7 +M__^Z'`"=Y0%0H./'_?_K!P"@X0$KH.,$$*#A1O;_ZX@PG^7L+`CC`W"@X;)@ +MD^$%8(;@%@``ZL8RH.$#,93G`0!SXQ]@A@,!8(8"$```"@``5N,?((;B!B"@ +MH7XQ%N(!,$-"=@#_YL(BH.$!8(;B@SW@00(AE.>C/>!!`3"#0A4C$N`````: +M>>[_ZQ\`%N/N__\:OC#7X0,`5N'E__^ZR_K_ZP``H.-!WXWB\(^]Z`````"E +M!@``(B)356(`````````Z""?Y0`PH.-P0"WIX$"?Y1DTPN5"'J#C"Y;80 +MQ.$`,,3E`3#$Y?[__^L``%#C`%#@$Q<``!K^___KK^O_ZP``4.,*```*J""? +MY4(>H..D`)_E_O__Z[80U.&<`)_E_O__ZY@`G^7^___K``#@XW"`O>C^___K +M``!0XP$```K%_?_K_O__ZV0PG^4`4*#C`2"@XP`@P^540)_E0AZ@XU`@G^50 +M`)_E_O__ZUP0E.50`)_E_O__ZP8T`.-(`)_ELQ"4X?[__^NP$=3A/`"?Y?[_ +M_^NR$=3A-`"?Y?[__^L!`*#C_O__ZP4`H.%P@+WHR-P,``````#6!@``M08` +M`-X&``#\!@``$@<``"4'```[!P``OP$```$`````````L+"P@$0```"PL+"` +MG````*\'L8!\`0``L+"J@-P!``"PL+"`[`$``+"PK(!8`@``L+"P@%P"``"P +ML+"`9`(``+"PL(!L`@``L+"P@'0"``"PL+"`>`(``+"PL(#@`@``L+"P@"0# +M``"PL*N`G`,``+"O!H"$!```K`.Q@)`%``"O!+*`?`8``+"PL("$!@``L+"P +M@)`&``"PL*Z`(`<``+"PL(!H!P``L+"J@/`'``"PL*J`+`@``+"PJH!0"0`` +ML*\$@'`*``"O"+*`(`\``*\BLH"\$```7X0@@#@2``"PL*J`"!0``*\(L8`@ +M%0``L*\$@)`6``"O`;&`O!<``+"PJ(!0&```L*\B@%`9``"PKRB`#!P``%^$ +M(H!D'0``L+"L@+@=``"PKR2`G!\``+"PKH#8(```L+"L@'0A``"PKR*`/"(` +M`*\&LH#`)@``L+"N@-`G``"PL*J`0"D``+"L'X"4*@``L+"L@"@M``"J`[&` +MI"T``+"PJ(#D+0``L+"H@$@N``"PL*Z`["X``+"PJH!,+P``J@.Q@,PO``"P +MK!^`6#$``+"O)H#H,P``L*\,@+PW``"PL*R`8#@``+"PK(#<.```L*X)@"@[ +M``"PL*J``#P``+"O((`@/0``KPBQ@'P_``"PKP2`:$$``+"PK(#D00``KPBQ +M@(!&``"PKRB`0$@``*\"LH!<2P``L*\&@"Q/``"O![&`H%```+"PKH#<40`` +ML*X?@`Q3``"O/P"`<%L``+"PJH!&5$P@5F5R`H`/#4^0F%D(&)L:R!I;F9O(&-N="`]("5D +M"@`\-3Y.;R!"860@8FQK(&EN9F\*`#PU/G-P87)E(#!X)7@L,'@E>"PP>"5X +M+#!X)7@L,'@E>"PP>"5X+#!X)7@L,'@E>`H`/#4^"`L +M('!&=&Q);F9O+3YS=&%R=%!H>4)L:R`]("5X"@`\-3YP1G1L26YF;RT^9G1L +M5F5R("5X("P@1E1,7U9%4E-)3TX@/2`E>`H`/#4^<$9T;$EN9F\M/G1O=&%L +M3&]G:6-";&L@)7@@+"!P1G1L26YF;RT^;6%X4&AY0FQK(#T@)7@*`#PU/G!" +M861";&M);F9O+3YC;G0@)60*`#PU/D=E=$)A9$)L:U1B;"!T;V\@;6%N>2!B +M860@8FQK"@`E"!%`H`/#4^1FQA`H`/#4^97)R;W(Z1V5T4F5M87`@4$%"(&ES +M(#`@+$Q"02`]("5X("P@;F5W(%!"02`]("5X("P@)7@@"@`\-3Y00D%,87-T +M('!B82`]("5D("`*`$9T;%-E=%-Y7-);F9O+G-Y"`*`$9T;$-A8VAE5W)I=&5"86-K +M"@`\-3Y&=&Q4:6UE2&]O:SI&=&Q#86-H941E;&%Y5W)I=&5!3$P*`#PU/F5X +M8VAA9V4@8FQO8VL@"Q$871E(#T@)7,*`#(P +M,3`Q,3@`3$]!1$52($943"!)3D9/.E9E`H`3F5E9"!U<&1A +M=&4@3&]A9&5R(2$A`#PU/D-A8VAE(%9E!``N0``!@8````````````` +M`0```````````````````````````````0``````````````!`#Q_P`````` +M``````````,``0`````````````````#``,``````````````````P`$``<` +M`````````````````0`*````0`````````````$``````````````````P`% +M``````````````````,`!@`'````1`````````````$`"@```)@````````` +M```!``<```"<`````````````0`*````>`$```````````$`!P```'P!```` +M```````!``H```#8`0```````````0`'````W`$```````````$`"@```.@! +M```````````!``T```#L`0``;`````(``0`'````[`$```````````$`"@`` +M`%0"```````````!``<```!8`@```````````0`'````7`(```````````$` +M!P```&0"```````````!``<```!L`@```````````0`'````=`(````````` +M``$`!P```'@"```````````!``H```#8`@```````````0`'````X`(````` +M``````$`"@```!P#```````````!``<````D`P```````````0`*````F`,` +M``````````$`'@```)P#``#H`````@`!``<```"<`P```````````0`*```` +M@`0```````````$`!P```(0$```````````!``H```",!0```````````0`' +M````D`4```````````$`"@```'`&```````````!``<```!\!@`````````` +M`0`'````A`8```````````$`"@```(P&```````````!`"8```"0!@``D``` +M``(``0`'````D`8```````````$`"@```!0'```````````!`#,````@!P`` +M2`````(``0`'````(`<```````````$`"@```&`'```````````!``<```!H +M!P```````````0`*````Z`<```````````$`!P```/`'```````````!``H` +M```H"````````````0`'````+`@```````````$`"@```#P)```````````! +M``<```!0"0```````````0`*````:`H```````````$`10```'`*``"P!``` +M`@`!``<```!P"@```````````0`*````T`X```````````$`4@```"`/``"< +M`0```@`!``<````@#P```````````0`*````J!````````````$`8````+P0 +M``!\`0```@`!``<```"\$````````````0`*````+!(```````````$`!P`` +M`#@2```````````!``H```"X$P```````````0!M````"!0``!@!```"``$` +M!P````@4```````````!``H````<%0```````````0""````(!4``'`!```" +M``$`!P```"`5```````````!``H```",%@```````````0"2````D!8``"P! +M```"``$`!P```)`6```````````!``H```"X%P```````````0"G````O!<` +M`)0````"``$`!P```+P7```````````!``H```!,&````````````0`'```` +M4!@```````````$`"@```$09```````````!``<```!0&0```````````0`* +M````_!L```````````$`!P````P<```````````!``H```!<'0`````````` +M`0`'````9!T```````````$`"@```+0=```````````!``<```"X'0`````` +M`````0`*````D!\```````````$`!P```)P?```````````!``H```#,(``` +M`````````0"X````V"```)P````"``$`!P```-@@```````````!``H```!L +M(0```````````0`'````="$```````````$`"@```#`B```````````!``<` +M```\(@```````````0`*````E"8```````````$`!P```,`F```````````! +M``H```#()P```````````0`'````T"<```````````$`"@```#0I```````` +M```!``<```!`*0```````````0`*````?"H```````````$`Q0```)0J``"4 +M`@```@`!``<```"4*@```````````0`*````'"T```````````$`!P```"@M +M```````````!``H```"8+0```````````0`'````I"T```````````$`"@`` +M`.`M```````````!``<```#D+0```````````0`*````0"X```````````$` +MTP```$@N``"D`````@`!``<```!(+@```````````0`*````Y"X````````` +M``$`!P```.PN```````````!``H```!(+P```````````0`'````3"\````` +M``````$`"@```,`O```````````!`.,```#,+P``C`$```(``0`'````S"\` +M``````````$`"@```$@Q```````````!`/4```!8,0``D`(```(``0`'```` +M6#$```````````$`"@```-@S```````````!``@!``#H,P``U`,```(``0`' +M````Z#,```````````$`"@```+`W```````````!``<```"\-P`````````` +M`0`*````6#@```````````$`!P```&`X```````````!``H```#8.``````` +M`````0`'````W#@```````````$`"@```!P[```````````!``<````H.P`` +M`````````0`*````^#L```````````$`!P`````\```````````!``H````4 +M/0```````````0`'````(#T```````````$`"@```&@_```````````!``<` +M``!\/P```````````0`*````7$$```````````$`&`$``&A!``!\`````@`! +M``<```!H00```````````0`*````X$$```````````$`)0$``.1!``"`(``&@````2``$`4`(`````````````$``` +M`%L"``#@`@``1````!(``0!I`@``)`,``'@````2``$`>P(````````````` +M$````(T"``"$!```#`$``!(``0"?`@``D`4``.P````2``$`K`(````````` +M````$````+,"``!\!@``"````!(``0#(`@`````````````0````V`(``(0& +M```,````$@`!`.X"`````````````!````#Y`@`````````````0````!@,` +M`&@'``"(````$@`!``T#``#P!P``/````!(``0`>`P`````````````0```` +M*`,``"P(```D`0``$@`!`#,#``!0"0``(`$``!(``0!!`P`````````````0 +M````40,`````````````$````&,#`````````````!````!N`P`````````` +M```0````?`,``#@2``#0`0``$@`!`)`#`````````````!````"8`P``4!@` +M```!```2``$`I0,``%`9``"\`@``$@`!`+(#```,'```6`$``!(``0"^`P`` +M9!T``%0````2``$`R0,``+@=``#D`0``$@`!`-@#``"<'P``/`$``!(``0#A +M`P``="$``,@````2``$`[P,``#PB``"$!```$@`!``$$``#`)@``$`$``!(` +M`0`6!```T"<``'`!```2``$`(00``$`I``!4`0``$@`!`#0$```H+0``?``` +M`!(``0!&!```I"T``$`````2``$`6P0``.0M``!D````$@`!`&<$``#L+@`` +M8````!(``0!Z!```3"\``(`````2``$`@P0`````````````$````)P$```` +M`````````!````"G!``````````````0````L`0``+PW``"D````$@`!`+T$ +M``!@.```?````!(``0#/!```W#@``$P"```2``$`X00``"@[``#8````$@`! +M`.L$````/```(`$``!(``0#X!``````````````0````$@4``"`]``!<`@`` +M$@`!`",%``!\/P``[`$``!(``0`N!0`````````````0````-04``$!(```< +M`P``$@`!`$<%``!<2P``T`,``!(``0!0!0``+$\``'0!```2``$`6P4``*!0 +M```\`0``$@`!`&,%``!P6P``&`$``!(``0!K!0`````````````0````=04` +M```````<````$0`(`($%````````!````!$``P"+!0```````.`@`0`1``0` +ME`4``.`@!```0`@`$0`$`)X%``#@(`$````"`!$`!`"L!0``X&`,``"````1 +M``0`O@4``.3@#``$````$0`$`,P%``#@(`,````!`!$`!`#2!0``X.`,``$` +M```1``0`X@4``.'@#``!````$0`$`/4%``#HX`P``$(``!$`!```9G1L+F,` +M)&$`)&0`17AC:%!A9V5296UA<$%D9`!&1D9086=E`$9T;$-A8VAE26YI=`!% +M>&-H4&%G95)E;6%P26YI=`!'971"861";&M48FP`3&]S=%!W&-H0FQK4F5C;W9E +M0!&=&Q086=E4F5A9`!&=&Q086=E +M5W)I=&4`1G1L1&5L87E77-07-05!R;V<`41E9F%U +M;'0`9G1L7VUA;&QO8P!F=&Q?9G)E90!%>&-H0FQK0VQO`8```*K``"`!@`` -M'<<``(@&```=QP``W`8``!S)```4!P```@0``!@'```"!```'`<```($``!< -M!P``'```< -MM0``6!X``!RU``!L'@``'+@``+P>`````` -M`"H"``"`````*@(``(@````J`@``D````"H"``"8````*@(``*`````J`@`` -MJ````"H"``"P````*@(``+@````J`@``P````"H"``#(````*@(``-`````J -M`@``V````"H"``#@````*@(``.@````J`@``\````"H"``#X````*@(````! -M```J`@``"`$``"H"```0`0``*@(``!@!```J`@``(`$``"H"```H`0``*@(` -M`#`!```J`@``.`$``"H"``!``0``*@(``$@!```J`@``4`$``"H"``!8`0`` -M*@(``&`!```J`@``:`$``"H"``!P`0``*@(``'@!```J`@``@`$``"H"``"( -M`0``*@(``)`!```J`@``F`$``"H"``"@`0``*@(``*@!```J`@``L`$``"H" -M``"X`0``*@(``,`!```J`@``R`$``"H"``#0`0``*@(``-@!```J`@``X`$` -M`"H"``#H`0``*@(``/`!```J`@``^`$``"H"`````@``*@(```@"```J`@`` -M$`(``"H"```8`@``*@(``"`"```J`@``*`(``"H"```P`@``*@(``#@"```J -+`@``0`(``"H"```` +M;%1I;65(;V]K1FQA9P!&=&Q4:6UE2&]O:U1I;65O=70`1G1L,D9L87-H4')O +M9T)U9@```$`````"!```F`````($```H`0``'*\``'@!```"!```I`$``!RQ +M``#8`0```@0``.@!```"!```"`(``!RT```8`@``'+$``"@"````8```*H``"`!@``'<,``(@&```=PP``W`8``!S%```4!P```@0` +M`!@'```"!```'`<```($``!!L``!R^``#(&P`` +M',L``/P;```"!````!P```*H```$'````J@```@<```"!```Y!P``!R^``!0 +M'0``'-,``%P=```"!```8!T```($``!X'0``'-0``(@=````````````\+@``'=X``$`N```"!```1"X```*H``#D+@```@0``.@N +M```"!```2"\```($``!X+P``'-P``'PO```P``,1/```<[0`` +M*%```!SL``!`4```'.T``)10```"NP``F%````($``"<4````@0```11```< +MM```/%$``!SP``"440``'.P``+Q1```<\```U%$```*[``#840```@0``!A2 +M```%P```*H``!\7````J@``(!<```"J```A%P```*H````````*@(````` +M````K0``"````"H"```0````*@(``!@````J`@``(````"H"```H````*@(` +M`#`````J`@``.````"H"``!`````*@(``$@````J`@``4````"H"``!8```` +M*@(``&`````J`@``:````"H"``!P````*@(``'@````J`@``@````"H"``"( +M````*@(``)`````J`@``F````"H"``"@````*@(``*@````J`@``L````"H" +M``"X````*@(``,`````J`@``R````"H"``#0````*@(``-@````J`@``X``` +M`"H"``#H````*@(``/`````J`@``^````"H"`````0``*@(```@!```J`@`` +M$`$``"H"```8`0``*@(``"`!```J`@``*`$``"H"```P`0``*@(``#@!```J +M`@``0`$``"H"``!(`0``*@(``%`!```J`@``6`$``"H"``!@`0``*@(``&@! +M```J`@``<`$``"H"``!X`0``*@(``(`!```J`@``B`$``"H"``"0`0``*@(` +M`)@!```J`@``H`$``"H"``"H`0``*@(``+`!```J`@``N`$``"H"``#``0`` +M*@(``,@!```J`@``T`$``"H"``#8`0``*@(``.`!```J`@``Z`$``"H"``#P +M`0``*@(``/@!```J`@````(``"H"```(`@``*@(``!`"```J`@``&`(``"H" +B```@`@``*@(``"@"```J`@``,`(``"H"```X`@``*@(````` ` end diff --git a/drivers/mtd/rknand/nand_config.h b/drivers/mtd/rknand/nand_config.h index 573f26726f88..e192b9e1b353 100755 --- a/drivers/mtd/rknand/nand_config.h +++ b/drivers/mtd/rknand/nand_config.h @@ -42,6 +42,7 @@ Revision: 1.00 #ifdef CONFIG_MTD_NAND_RK29XX_DEBUG #undef RKNAND_DEBUG +#define DEBUG_MSG #define RKNAND_DEBUG(format, arg...) \ printk(KERN_NOTICE format, ## arg); #else diff --git a/drivers/mtd/rknand/rknand_base.c b/drivers/mtd/rknand/rknand_base.c index 0d6e0817b8a9..1cd792f00c80 100755 --- a/drivers/mtd/rknand/rknand_base.c +++ b/drivers/mtd/rknand/rknand_base.c @@ -22,39 +22,29 @@ #include #include "api_flash.h" +extern int rknand_queue_read(int Index, int nSec, void *buf); +extern int rknand_queue_write(int Index, int nSec, void *buf,int mode); +extern int rknand_buffer_init(void); +extern void rknand_buffer_shutdown(void); #define DRIVER_NAME "rk29xxnand" - +const char rknand_base_version[] = "rknand_base.c version: 4.20 20101118"; #define NAND_DEBUG_LEVEL0 0 #define NAND_DEBUG_LEVEL1 1 #define NAND_DEBUG_LEVEL2 2 #define NAND_DEBUG_LEVEL3 3 -long FTLWriteCount =0; -long FTLReadWriteTime =0; -long FTLSwapWriteCount =0; -long FTLPageWriteCount =0; - +//#define PAGE_REMAP #ifndef CONFIG_RKFTL_PAGECACHE_SIZE #define CONFIG_RKFTL_PAGECACHE_SIZE 64 //¶¨ÒåpageÓ³ÉäÇø´óС£¬µ¥Î»ÎªMB,mount ÔÚ/data/dataÏ¡£ #endif -#define use_image - -#ifdef use_image unsigned long SysImageWriteEndAdd = 0; int g_num_partitions = 0; -#endif #ifdef CONFIG_MTD_NAND_RK29XX_DEBUG static int s_debug = CONFIG_MTD_NAND_RK29XX_DEBUG_VERBOSE; -//module_param(s_debug, int, 0); -//MODULE_PARM_DESC(s_debug, "Set Debug Level 0=quiet, 5=noisy"); #undef NAND_DEBUG -/*#define NAND_DEBUG(n, format, arg...) \ - if (n <= s_debug) { \ - printk(KERN_NOTICE __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ - }*/ #define NAND_DEBUG(n, format, arg...) \ if (n <= s_debug) { \ printk(format,##arg); \ @@ -65,18 +55,10 @@ static int s_debug = CONFIG_MTD_NAND_RK29XX_DEBUG_VERBOSE; static const int s_debug = 0; #endif -long RkFtlWriteCount; - /* * RK28 LBA PARTITIONS,the size and offset value below is default value in this program, * when RK28 LBA FLASH init,the value will be modify to the value in the nand flash. */ -#define MAX_FLASH_PARTITION 2 - -#define ROOTFS_PART_SIZE 300 -#define PARA_PART_SIZE 1 -#define KERNEL_PART_SIZE 4 - static struct mtd_partition rk28_partition_info[] = { { name: "misc", @@ -104,21 +86,21 @@ static struct mtd_partition rk28_partition_info[] = { }; - +#ifdef PAGE_REMAP static struct mtd_partition rk28_page_part_info[] = { { name: "pagecache", offset: 0, - size: CONFIG_RKFTL_PAGECACHE_SIZE * 0x800,//32MB + size: CONFIG_RKFTL_PAGECACHE_SIZE * 0x800*0x200,//32MB }, { name: "swap", - offset: (CONFIG_RKFTL_PAGECACHE_SIZE) * 0x800, - size: 64 * 0x800,//64MB + offset: (CONFIG_RKFTL_PAGECACHE_SIZE) * 0x800*0x200, + size: 64 * 0x800*0x200,//64MB }, }; - +#endif /* * onenand_state_t - chip states * Enumeration for OneNAND flash chip state @@ -148,6 +130,106 @@ struct rknand_info { }; struct rknand_info * gpNandInfo; + +#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)) +#define NANDPROC_ROOT (&proc_root) +#else +#define NANDPROC_ROOT NULL +#endif + +static struct proc_dir_entry *my_proc_entry; +extern int rkNand_proc_ftlread(char *page); +extern int rkNand_proc_bufread(char *page); +static int rkNand_proc_read(char *page, + char **start, + off_t offset, int count, int *eof, void *data) +{ + char *buf = page; + int step = offset; + *(int *)start = 1; + if(step == 0) + { + buf += sprintf(buf, "%s\n", rknand_base_version); + buf += rkNand_proc_ftlread(buf); +#ifdef CONFIG_MTD_RKNAND_BUFFER + buf += rkNand_proc_bufread(buf); +#endif + } + return buf - page < count ? buf - page : count; +} + +static void rk28nand_create_procfs(void) +{ + /* Install the proc_fs entry */ + my_proc_entry = create_proc_entry("rk29xxnand", + S_IRUGO | S_IFREG, + NANDPROC_ROOT); + + if (my_proc_entry) { + my_proc_entry->write_proc = NULL; + my_proc_entry->read_proc = rkNand_proc_read; + my_proc_entry->data = NULL; + } +} + +void rkNand_cond_resched(void) +{ + if(gpNandInfo->rknand.rknand_schedule_enable == 1) + { + //msleep(1); + //mdelay(1); + cond_resched(); + } +} + +#ifdef CONFIG_MTD_RKNAND_BUFFER +static int rk28xxnand_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + int ret = 0; + int sector = len>>9; + int LBA = (int)(from>>9); + //printk("rk28xxnand_read: from=%x,len=%x,\n",(int)from,len); + if(sector) + { + ret = rknand_queue_read(LBA, sector, buf); + } + *retlen = len; + return 0;//ret; +} + +static int rk28xxnand_write(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, const u_char *buf) +{ + int ret = 0; + int sector = len>>9; + int LBA = (int)(from>>9); + //printk("*"); + //printk(KERN_NOTICE "write: from=%lx,len=%x\n",(int)from,len); + if(sector)// cmy + { + if(LBA < SysImageWriteEndAdd)//0x4E000) + { + printk(">>> FtlWriteImage: LBA=0x%08X sector=%d\n",LBA, sector); + ret = rknand_queue_write(LBA, sector, (void *)buf,1); + } + else + { + ret = rknand_queue_write(LBA, sector, (void *)buf,0); + } + } + *retlen = len; + return 0;//ret; +} +#else + +void rknand_queue_cond_resched(void) +{ + ; +} + static int rknand_get_device(int new_state) { struct rknand_chip *nand_info = &gpNandInfo->rknand; @@ -176,27 +258,12 @@ static void rknand_release_device(void) wake_up(&nand_info->wq); } -void rkNand_cond_resched(void) -{ - if(gpNandInfo->rknand.rknand_schedule_enable == 1) - { - //msleep(1); - //mdelay(1); - cond_resched(); - } -} - static int rk28xxnand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { int ret = 0; int sector = len>>9; int LBA = (int)(from>>9); - //printk(KERN_NOTICE "read: from=%x,len=%x,\n",(int)from,len); - NAND_DEBUG(NAND_DEBUG_LEVEL1,"-"); - //FTLReadWriteTime++; - //if(len&511) - // printk("rk28xxnand_read: from=%x,len=%x,\n",(int)from,len); rknand_get_device(FL_READING); if(sector) { @@ -209,74 +276,47 @@ static int rk28xxnand_read(struct mtd_info *mtd, loff_t from, size_t len, return 0;//ret; } -// cmy: before cache part use FtlWriteImage, after cache(include cache) use FtlWrite -static int write_Image(int LBA, int sector, u_char* buf) -{ - int remain_sector = sector; - int write_sector = 0; - u_char* data = buf; - int index = LBA; - int ret = 0; - while(remain_sector > 0) - { - write_sector = remain_sector>32?32:remain_sector; - ret = FtlWriteImage(index, write_sector, data); - data += write_sector<<9; - index += write_sector; - remain_sector -= write_sector; - } - return ret; -} - static int rk28xxnand_write(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) + size_t *retlen, const u_char *buf) { int ret = 0; int sector = len>>9; int LBA = (int)(from>>9); //NAND_DEBUG(NAND_DEBUG_LEVEL0,"+"); - FTLWriteCount+=sector; - FTLReadWriteTime++; - //dump_stack(); //printk(KERN_NOTICE "write: from=%lx,len=%x\n",(int)from,len); rknand_get_device(FL_WRITING); if(sector)// cmy { -#ifdef use_image if(LBA < SysImageWriteEndAdd)//0x4E000) { printk(">>> FtlWriteImage: LBA=0x%08X sector=%d\n",LBA, sector); - - ret = FtlWriteImage(LBA&0xFFFFFFE0, sector, buf);// LBA align to 32 + ret = FtlWriteImage(LBA&0xFFFFFFE0, sector, (void *)buf);// LBA align to 32 } -#else - if(LBA<0x4E000) - ret = write_Image(LBA, sector, buf); -#endif else { - ret = FtlWrite(2,LBA, sector, buf); + ret = FtlWrite(2,LBA, sector, (void *)buf); } } rknand_release_device(); *retlen = len; return 0;//ret; } +#endif +#ifdef PAGE_REMAP static int rk28xxnand_page_write(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) + size_t *retlen, const u_char *buf) { int ret = 0; int sector = len; int LBA = (int)(from); NAND_DEBUG(NAND_DEBUG_LEVEL1,"*"); - FTLWriteCount+=sector; //printk("+"); //printk(KERN_NOTICE "pagewrite: from=%lx,len=%x\n",(int)from,len); rknand_get_device(FL_WRITING); if(sector)// cmy { - ret = FtlPageWrite(LBA, sector, buf); + ret = FtlPageWrite(LBA, sector, (void *)buf); } rknand_release_device(); *retlen = len; @@ -284,12 +324,11 @@ static int rk28xxnand_page_write(struct mtd_info *mtd, loff_t from, size_t len, } static int rk28xxnand_page_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) + size_t *retlen, u_char *buf) { int ret = 0; int sector = len; int LBA = (int)(from); - //printk(KERN_NOTICE "read: from=%x,len=%x,\n",(int)from,len); NAND_DEBUG(NAND_DEBUG_LEVEL2,"-"); //printk("-"); //if(len&511) @@ -297,99 +336,46 @@ static int rk28xxnand_page_read(struct mtd_info *mtd, loff_t from, size_t len, rknand_get_device(FL_READING); if(sector) { - ret = FtlPageRead(LBA, sector, buf); + ret = FtlPageRead(LBA, sector,(void *) buf); } rknand_release_device(); *retlen = len; return 0;//ret; } - +#endif static int rk28xxnand_erase(struct mtd_info *mtd, struct erase_info *instr) { int ret = 0; if (instr->callback) instr->callback(instr); - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_erase,add:%x,len:%x\n",instr->addr,instr->len); + NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_erase,add:0x%012llx,len:0x%012llx\n",instr->addr,instr->len); return ret; } -static int rk28xxnand_read_oob(struct mtd_info *mtd, loff_t from, - struct mtd_oob_ops *ops) -{ - int ret = 0; - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_read_oob\n"); - return ret; -} - - -static int rk28xxnand_write_oob(struct mtd_info *mtd, loff_t to, - struct mtd_oob_ops *ops) -{ - int ret=0; - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_write_oob\n"); - return ret; -} - -static int rk28xxnand_suspend(struct platform_device *dev, pm_message_t pm) -{ - gpNandInfo->rknand.rknand_schedule_enable = 0; - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xx_nand_suspend: \n"); - return 0; -} - -static int rk28xxnand_resume(struct platform_device *dev) -{ - gpNandInfo->rknand.rknand_schedule_enable = 1; - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xx_nand_resume: \n"); - return 0; -} - -static int rk28xxnand_block_isbad(struct mtd_info *mtd, loff_t ofs) -{ - //printk("rk28xxnand_block_isbad: \n"); - return 0; -} - -static int rk28xxnand_block_markbad(struct mtd_info *mtd, loff_t ofs) -{ - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_block_markbad: \n"); - return 0; -} - static void rk28xxnand_sync(struct mtd_info *mtd) { - /* Grab the lock and see if the device is available */ - rknand_get_device(FL_SYNCING); - /* Release it and go back */ - rknand_release_device(); NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_sync: \n"); } -static int rk28xxnand_lock(struct mtd_info *mtd, loff_t ofs, size_t len) -{ - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_lock: \n"); - return 0; -} - -static int rk28xxnand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) -{ - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_unlock: \n"); - return 0; -} - static int rk28xxnand_init(struct rknand_info *nand_info) { struct mtd_info *mtd = &nand_info->mtd; - struct mtd_info *page_mtd = &nand_info->page_mtd; struct rknand_chip *rknand = &nand_info->rknand; +#ifdef PAGE_REMAP + struct mtd_info *page_mtd = &nand_info->page_mtd; +#endif rknand->state = FL_READY; rknand->rknand_schedule_enable = 1; rknand->pFlashCallBack = NULL; init_waitqueue_head(&rknand->wq); NAND_DEBUG(NAND_DEBUG_LEVEL0,"FTLInit ...: \n"); - if(FTLInit()) +#ifdef PAGE_REMAP + if(FTLInit()) +#else + if(FTLInit_WithoutPageRemap()) +#endif { NAND_DEBUG(NAND_DEBUG_LEVEL0,"FTLInit Error: \n"); return -ENXIO; @@ -402,8 +388,8 @@ static int rk28xxnand_init(struct rknand_info *nand_info) mtd->oobsize = 0; mtd->oobavail = 0; mtd->ecclayout = 0; - mtd->erasesize = FlashGetPageSize()*0x200; //sector - mtd->writesize = FlashGetPageSize()*0x200; + mtd->erasesize = 8*0x200; //sectorFlashGetPageSize() + mtd->writesize = 8*0x200; //FlashGetPageSize() // Fill in remaining MTD driver data mtd->type = MTD_NANDFLASH;//MTD_RAM;// @@ -413,27 +399,28 @@ static int rk28xxnand_init(struct rknand_info *nand_info) mtd->unpoint = NULL; mtd->read = rk28xxnand_read; mtd->write = rk28xxnand_write; - mtd->read_oob = rk28xxnand_read_oob; - mtd->write_oob = rk28xxnand_write_oob; + mtd->read_oob = NULL; + mtd->write_oob = NULL; mtd->panic_write = NULL; mtd->sync = rk28xxnand_sync; - mtd->lock = rk28xxnand_lock; - mtd->unlock = rk28xxnand_unlock; - mtd->suspend = rk28xxnand_suspend; - mtd->resume = rk28xxnand_resume; - mtd->block_isbad = rk28xxnand_block_isbad; - mtd->block_markbad = rk28xxnand_block_markbad; + mtd->lock = NULL; + mtd->unlock = NULL; + mtd->suspend = NULL; + mtd->resume = NULL; + mtd->block_isbad = NULL; + mtd->block_markbad = NULL; mtd->owner = THIS_MODULE; - page_mtd->size = FtlGetPageZoneCapacity(); +#ifdef PAGE_REMAP + page_mtd->size = FtlGetPageZoneCapacity()*0x200; //readflash modify rk28_partition_info - NAND_DEBUG(NAND_DEBUG_LEVEL0,"page_mtd->size: %x\n",page_mtd->size); + NAND_DEBUG(NAND_DEBUG_LEVEL0,"page_mtd->size: 0x%012llx\n",page_mtd->size); page_mtd->oobsize = 0; page_mtd->oobavail = 0; page_mtd->ecclayout = 0; - page_mtd->erasesize = FlashGetPageSize(); //sector - page_mtd->writesize = FlashGetPageSize(); + page_mtd->erasesize = FlashGetPageSize()*0x200; //sector + page_mtd->writesize = FlashGetPageSize()*0x200; // Fill in remaining MTD driver data page_mtd->type = MTD_NANDFLASH;//MTD_RAM;// @@ -443,20 +430,21 @@ static int rk28xxnand_init(struct rknand_info *nand_info) page_mtd->unpoint = NULL; page_mtd->read = rk28xxnand_page_read; page_mtd->write = rk28xxnand_page_write; - page_mtd->read_oob = rk28xxnand_read_oob; - page_mtd->write_oob = rk28xxnand_write_oob; + page_mtd->read_oob = NULL; + page_mtd->write_oob = NULL; page_mtd->panic_write = NULL; page_mtd->sync = rk28xxnand_sync; - page_mtd->lock = rk28xxnand_lock; - page_mtd->unlock = rk28xxnand_unlock; - page_mtd->suspend = rk28xxnand_suspend; - page_mtd->resume = rk28xxnand_resume; - page_mtd->block_isbad = rk28xxnand_block_isbad; - page_mtd->block_markbad = rk28xxnand_block_markbad; + page_mtd->lock = NULL; + page_mtd->unlock = NULL; + page_mtd->suspend = NULL; + page_mtd->resume = NULL; + page_mtd->block_isbad = NULL; + page_mtd->block_markbad = NULL; page_mtd->owner = THIS_MODULE; +#endif - return 0; + return 0; } @@ -472,7 +460,6 @@ const char *part_probes[] = { "cmdlinepart", NULL }; static int rk28xxnand_add_partitions(struct rknand_info *nand_info) { - NAND_DEBUG(NAND_DEBUG_LEVEL0,"Enter rk28xxnand_add_partitions\n"); #ifdef CONFIG_MTD_CMDLINE_PARTS int num_partitions = 0; @@ -483,16 +470,13 @@ static int rk28xxnand_add_partitions(struct rknand_info *nand_info) int i; for (i = 0; i < num_partitions; i++) { - //printk(KERN_ERR"111 offset 0x%012llx size :0x%012llx\n",nand_info->parts[i].offset, nand_info->parts[i].size); nand_info->parts[i].offset *= 0x200; nand_info->parts[i].size *=0x200; //printk(KERN_ERR"offset 0x%012llx size :0x%012llx\n",nand_info->parts[i].offset, nand_info->parts[i].size); } nand_info->parts[num_partitions - 1].size = nand_info->mtd.size - nand_info->parts[num_partitions - 1].offset; -#ifdef use_image g_num_partitions = num_partitions; -#endif return add_mtd_partitions(&nand_info->mtd, nand_info->parts, num_partitions); } #endif @@ -501,18 +485,16 @@ static int rk28xxnand_add_partitions(struct rknand_info *nand_info) // rk28_partition_info[1].size = nand_info->mtd.size - ((ROOTFS_PART_SIZE + PARA_PART_SIZE + KERNEL_PART_SIZE)*0x100000); // rk28_partition_info[2].offset = rk28_partition_info[1].size + rk28_partition_info[1].offset; -#ifdef use_image g_num_partitions = sizeof(rk28_partition_info)/sizeof(struct mtd_partition); -#endif return add_mtd_partitions(&nand_info->mtd, rk28_partition_info, sizeof(rk28_partition_info)/sizeof(struct mtd_partition));//MAX_FLASH_PARTITION); } -static int __devinit rk28xxnand_probe(struct platform_device *pdev) +static int rknand_probe(struct platform_device *pdev) { struct rknand_info *nand_info; struct mtd_partition *parts; int i; - struct resource *res = pdev->resource; + //struct resource *res = pdev->resource; int err = 0; NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_probe: \n"); gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL); @@ -534,7 +516,14 @@ static int __devinit rk28xxnand_probe(struct platform_device *pdev) err = -ENXIO; goto exit_free; } - +#ifdef CONFIG_MTD_RKNAND_BUFFER + if(rknand_buffer_init()) + { + err = -ENXIO; + goto exit_free; + } +#endif + rk28nand_create_procfs(); /*{ char pbuf[512]; GetSNSectorInfo(pbuf); @@ -543,29 +532,23 @@ static int __devinit rk28xxnand_probe(struct platform_device *pdev) } */ rk28xxnand_add_partitions(nand_info); - return 0; - - #if 0 - nand_info->page_mtd.name = "pagecache"; - add_mtd_device(&nand_info->page_mtd); - #else - //rk28_page_part_info[1].size = nand_info->page_mtd.size - rk28_page_part_info[0].size; - //add_mtd_partitions(&nand_info->page_mtd, rk28_page_part_info, 2); - #endif - -#ifdef use_image + +#ifdef PAGE_REMAP + rk28_page_part_info[1].size = nand_info->page_mtd.size - rk28_page_part_info[0].size; + add_mtd_partitions(&nand_info->page_mtd, rk28_page_part_info, 2); +#endif + parts = nand_info->parts; for(i=0;i>> part[%d]: name=%s offset=0x%X\n", i, parts[i].name, parts[i].offset); + printk(">>> part[%d]: name=%s offset=0x%012llx\n", i, parts[i].name, parts[i].offset); if(strcmp(parts[i].name,"cache") == 0) { - SysImageWriteEndAdd = parts[i].offset; - printk(">>> SysImageWriteEndAdd=0x%X\n", SysImageWriteEndAdd); + SysImageWriteEndAdd = (unsigned long)parts[i].offset>>9;//sector + printk(">>> SysImageWriteEndAdd=0x%lx\n", SysImageWriteEndAdd); break; } } -#endif FtlSetSysProtAddr(SysImageWriteEndAdd); dev_set_drvdata(&pdev->dev, nand_info); @@ -578,8 +561,8 @@ static int __devinit rk28xxnand_probe(struct platform_device *pdev) return err; } - -static int __devexit rknand_remove(struct device *dev) +#if 0 +static int rknand_remove(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct rknand_info *nand_info = dev_get_drvdata(&pdev->dev); @@ -600,21 +583,50 @@ static int __devexit rknand_remove(struct device *dev) } return 0; } - -void rk28xxnand_shutdown(struct platform_device *pdev) +#endif +static int rknand_suspend(struct platform_device *pdev, pm_message_t state) { - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_shutdown\n"); - //rknand_get_device(FL_UNVALID); - //FtlClose(); - //rknand_release_device(); + gpNandInfo->rknand.rknand_schedule_enable = 0; + NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_suspend: \n"); + return 0; +} + +static int rknand_resume(struct platform_device *pdev) +{ + gpNandInfo->rknand.rknand_schedule_enable = 1; + NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_resume: \n"); + return 0; +} + +void rknand_shutdown(struct platform_device *pdev) +{ +#ifdef CONFIG_MTD_RKNAND_BUFFER + NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_shutdown...\n"); + gpNandInfo->rknand.rknand_schedule_enable = 0; + rknand_buffer_shutdown(); +#else + struct rknand_chip *nand_info = &gpNandInfo->rknand; + nand_info->rknand_schedule_enable = 0; + NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_shutdown...\n"); + if (nand_info->state == FL_READY) + { + nand_info->state = FL_UNVALID; + FtlClose(); + rknand_release_device(); + } + else + { + nand_info->pFlashCallBack = FtlClose; + } +#endif } static struct platform_driver rknand_driver = { - .probe = rk28xxnand_probe, - .remove = rknand_remove, - .suspend = rk28xxnand_suspend, - .resume = rk28xxnand_resume, - .shutdown = rk28xxnand_shutdown, + .probe = rknand_probe, + //.remove = rknand_remove, + .suspend = rknand_suspend, + .resume = rknand_resume, + .shutdown = rknand_shutdown, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -636,17 +648,16 @@ static int __init rknand_init(void) static void __exit rknand_exit(void) { - NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_exit: \n"); - rknand_get_device(FL_UNVALID); - FtlClose(); - rknand_release_device(); + //NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_exit: \n"); + //rknand_get_device(FL_UNVALID); + //FtlClose(); + //rknand_release_device(); platform_driver_unregister(&rknand_driver); } module_init(rknand_init); module_exit(rknand_exit); - #if 0//def CONFIG_rknand /* ×¢²áÒ»¸ösys dev £¬ÔڹػúºÍ¸´Î»Ê±»Øµ÷£¬°Ñflash¹Ø¼üÐÅϢдµ½nand flashÖУ¬Ï´οª»úʱ¿ÉÒÔ¿ìËÙ¿ª»ú¡£ @@ -658,8 +669,8 @@ module_exit(rknand_exit); static int rknand_sys_suspend(struct sys_device *dev, pm_message_t state) { struct rknand_chip *nand_info = &gpNandInfo->rknand; - NAND_DEBUG(NAND_DEBUG_LEVEL0,"...rknand_sys_suspend...\n"); extern void FtlCacheWriteBack(void); + NAND_DEBUG(NAND_DEBUG_LEVEL0,"...rknand_sys_suspend...\n"); nand_info->rknand_schedule_enable = 0; if (nand_info->state == FL_READY) { diff --git a/drivers/mtd/rknand/rknand_buffer.uu b/drivers/mtd/rknand/rknand_buffer.uu new file mode 100644 index 000000000000..a86000c4455c --- /dev/null +++ b/drivers/mtd/rknand/rknand_buffer.uu @@ -0,0 +1,199 @@ +begin 644 rknand_buffer.o +M?T5,1@$!`0````````````$`*``!```````````````T$@``````!30````` +M`"@`$``-`"`PG^4"%:#C'""?Y1@0@^4!`(+@"""#Y0P`@^40((/E%!"#Y1[_ +M+^'X_W\``````#`PG^4!$(#@$""3Y0(`4>$!$&*`&!"#A0S`DY4(`).5#"!B +MD!@@@Y4"(&"0`A"!D!00@^4>_R_A^/]_`%PPG^48$)/E``!1X0@``+H0()/E +M`1!@X!3`D^48$(/E`!""X`P`8.`0$(/E%`"#Y0D``.H4()/E`A!AX```4>$` +M(*"S`1!@H`@@DZ48$(.E``""H!00@Z40`(.E`@"@X1[_+^'X_W\`%#"?Y10` +MD^48,)/E``!CX`,`4.$#`*"Q'O\OX?C_?P``,)#E``!3XP00@`4(,)`5$!"# +M%0`PH.,($(#E$#"!Y0`PD.4!,(/B`#"`Y1[_+^%P0"WIH!"?Y:`@G^4`4*#A +M_O__ZYA`G^68$)_E%""4Y0!@A>`&`*#A_O__ZQ@@E.6$$)_E`&"&X`8`H.'^ +M___K#!"4Y0@@E.44,)3E`2!BX&@0G^4"(&/@`&"&X`8`H.'^___K-""4Y500 +MG^4`8(;@!@"@X?[__^LH()3E1!"?Y0!@AN`&`*#A_O__ZT`@E.4T$)_E`$"& +MX`0`H.'^___K``"$X```9>!P@+WH``````````#X_W\`!````!8````I```` +M0````%4```!I````$$`MZ0#`H.$``)#E`@!0XPH```H6`%#C#@``"@$`4.,` +M`.`3$("]&`0PG.4"`*#C"!"D-(*#A?UW" +MXQ,0H.,_4,7C#`"5Y?[__^M\`Y_E_O__ZX``#/$$,)7E`3"#X@0PA>4`H*#C +M9$.?Y0%PH.,*8*#A*X$`XWX``.HT,)3E`0!3XQL``,HH,)3E``!3XQ@``!H( +M`%KA%@``R@PPE>4TD)3E`'"#Y8``"/$$,)7E`3!#X@0PA>4`,)7E`@`3XP`` +M``K^___K`0!9XP,``!ID`*#C`:"*XO[__^L```#J_O__ZX``#/$$,)7E`3"# +MX@0PA>5?``#J@``(\00PE>4!,$/B!#"%Y0`PE>4"`!/C````"O[__^NX`I_E +M_O__ZX``#/$$,)7E`3"#X@0PA>4H,)3E``!3XRX``!HXH)3E-""4Y1`PFN4! +M($+B)*"$Y30@A.4X,(3E@``(\00PE>4!,$/B!#"%Y0`PE>4"`!/C````"O[_ +M_^L*`*#AC___ZX``#/$$,)7E`3"#X@0PA>5`,)3E)&"$Y0``4^-$H(0%2#"4 +M%1"@@Q5(H(3E$&"*Y4`PE.40()3E`3"#XD`PA.4,$)KE!#":Y8$T@^`"`%/A +M`S!B@!@PA(4,`)25"!"4E0`@8I`8((25`B!AD`(P@Y`4,(3E%P``ZBR@E.4H +M()3E$#":Y0$@0N(H((3E+#"$Y8``"/$$,)7E`3!#X@0PA>4`,)7E`@`3XP`` +M``K^___K"@"@X6'__^N```SQ!#"5Y0$P@^($,(7E%`":Y0``4.,````*_O__ +MZWP!G^4#$*#C`2"@XP`PH./^___K9`&?Y?[__^L`H*#C_O__ZP``4.-]__\* +M@``(\0T@H.%_/<+C/S##XP0@D^4!($+B!""#Y0`PD^4"`!/C````"O[__^LH +M`9_E_O__ZQX`H./^___K`!"@X0P!G^7^___K`&!0XCP``!J```SQ#2"@X7\] +MPN,_,,/C!""3Y0$@@N($((/EW$"?Y2(``.HX4)3E-""4Y04`H.$0,)7E`2!" +MXB10A.4T((3E.#"$Y2C__^M`,)3E)&"$Y0``4^-$4(0%2#"4%1!0@Q5(4(3E +M$&"%Y4`PE.40()3E`3"#XD`PA.4,$)7E!#"5Y8$T@^`"`%/A`Q!BX!@0A(4, +M`)25"!"4E100A(4`(&*0&""$E0(@89`",(.0%#"$E30PE.4``%/CV?__&O[_ +M_^N```CQ#2"@X7\]PN,_,,/C!""3Y0$@0N($((/E`#"3Y0(`$^,````*_O__ +MZQ``G^7^___K``"@X_"'O>A]````^/]_```````4`(``F@```'!`+>F```SQ +M#2"@X7]-PN,_0,3C!#"4Y0$P@^($,(3EG%"?Y1<``.HL8)7E*""5Y1`PEN4! +M($+B*""%Y2PPA>6```CQ!#"4Y0$P0^($,(3E`#"4Y0(`$^,````*_O__ZP8` +MH.'<_O_K%#"6Y0``4^(````*_O__ZX``#/$$,)3E`3"#X@0PA.4H,)7E``!3 +MX^3__QJ```CQ#2"@X7\]PN,_,,/C!""3Y0$@0N($((/E`#"3Y0(`$^-P@+T( +M<$"]Z/[__^KX_W\`!#"?Y4P`D^7^___J^/]_`+0PG^7P1RWI`H"@X20@D^4! +M8*#A.$"3Y0!0H.$``%+C@:2@X0!P@>`"0*`1'@``Z@@0E.4%`%'A"@``N@<` +M4>$8``"J#""4Y0`!`&7@!!"4Y0(`4^&`!(C@@R2@T0T``-H+``#J#""4 +MY0(@@>`%`%+A"P``V@(@9>`%$&'@!@!2X00PE.4(`*#A"B"@P8$4@^````#* +M@B2@X0``4N,````*_O__ZQ!`E.4``%3CWO__&@0`H.'PA[WH^/]_`%0PG^5P +M0"WI`$"!X"3`D^4X,)/E``!D)_3<+C`%"@X3]`Q.,`$*#C!@"@X10@H.,,<)3E +M_O__ZP2!G^4!H*#C`#&?Y0APC>4,,(WE@``,\00PE.4!,(/B!#"$Y4`@F.7< +M,)_E``!2XR```-H8()CE%!"8Y0$08N`"`%'A`2"@H0(@H+$%`%+A&```ND1` +MD^4``%7C0!"3Y1`@E.4!$$'B0!"#Y40@@^4`,*#C!#"$Y0(```H%`*#A_O__ +MZP0`A.6```CQ#2"@X7\]PN,_,,/C!""3Y0$@0N($((/E`#"3Y0(`$^,3```* +M_O__ZQ$``.J```CQ!#"4Y0$P0^($,(3E`#"4Y0(`$^,````*_O__ZPPPE.4` +MH(/E+`"?Y080H.'^___K_O__ZQP`G^4&$*#A_O__Z\3__^H$`*#A'-"-XO"% +MO>CX_W\``````!0`@`#X3RWIR$&?Y0"`H.$!4*#A`I"@X0.PH.%,`)3E@:2@ +MX?[__^N```SQ#2"@X7]MPN,_8,;C!#"6Y0$P@^($,(;E-#"4Y0``4^,E``#: +M/'"4Y0PPE^4(()?E`B"#X`@`4N$?```:&""4Y0H`4N$<``"Z!!"7Y1``E.6# +M%('@``!1X1<``!H!"U/C%0``RA0PE.4*$('@`B!JX!`0A.48((3E`S!JX!0P +MA.4)$*#A#`"7Y0H@H.$$,)?E@`2#X/[__^L,,)?E!5"#X`Q0A^6```CQ!#"6 +MY0$P0^($,(;E`#"6Y38``.J```CQ#2"@X7\]PN,_,,/C!""3Y0$@0N($((/E +M`#"3Y0(`$^,````*_O__ZPH`H.'^___K`$"@X8``#/$-(*#A?SW"XS\PP^,$ +M()/E`2""X@0@@^4``%OC"("`Y0*PH`,6L*`3#%"`Y0H@H.$`L(#E`#"@XPD0 +MH.$4,(#E!`"0Y?[__^MD,)_E-""3Y0``4N,\0(,%.$"#!3P@DQ400((5`""@ +MXSQ`@Q5`,)_E$""$Y30@D^4!((+B-""#Y8``"/$-(*#A?SW"XS\PP^,$()/E +M`2!"X@0@@^4`,)/E`@`3XP````K^___K``"@X_B/O>CX_W\`\$4MZ7R"G^44 +MT$WB`'"@X1`PC>("4*#A3`"8Y0`@H.,,("/E`6"@X00P@^(,,(WE"#"-Y?[_ +M_^N```SQ#2"@X7]-PN,_0,3C!#"4Y0$P@^($,(3E-#"8Y0``4^,+``"Z!P"@ +MX080H.$%(*#A_O__ZP``4.,%```*@``(\00PE.4!,$/B!#"$Y0`PE.5W``#J +M@``(\0T@H.%_/<+C/S##XP0@D^4!($+B!""#Y0`PD^4"`!/C````"O[__^L- +M,*#AQ`&?Y7]-P^/^___K/T#$XP"@4.(7```*!Q"@X08@H.$%,*#A`@"@X_[_ +M_^N```SQ!#"4Y0$P@^($,(3E!P"@X080H.$%(*#A_O__ZX``"/$$,)3E`3!# +MX@0PA.4`,)3E`@`3XP````K^___K6`&?Y?[__^M0``#J_O__ZP"`H.&```SQ +M!#"4Y0$P@^($,(3E$$"-X@AP@.4,8(#E`3"@XR@`@.@D$9_E#*`DY00`A.+^ +M___K##&?Y11`B.4H()/E``!2XS"`@P4L@(,%,""3%1"`@A4`(*#C,("#%>0P +MG^40((CE*""3Y0$@@N(H((/E@``(\0T@H.%_/<+C/S##XP0@D^4!($+B!""# +MY0`PD^4"`!/C````"O[__^ND0)_E3`"4Y?[__^L$`(WB_O__ZX``#/$-(*#A +M?SW"XS\PP^,$()/E`2""X@0@@^4%(*#A!P"@X080H.'^___K0#"4Y0`@H.,` +M`%/C2("$!42`A`5(,)05$("#%4@PG^5(@(05$""(Y4`@D^4!((+B0""#Y8`` +M"/$-(*#A?SW"XS\PP^,$()/E`2!"X@0@@^4`,)/E`@`3XP````K^___K``"@ +MXQ30C>+PA;WH^/]_``````!(8(``<$`MZ80`G^5($`;C_O__ZWPPG^5\()_E +M"#`#Y1@P@^("`%/A^___&FPPG^5(0`;C:!"?Y0(%H.-D4)_E`""@XP#`@>`8 +M`(/E!""#YU!`@^(T((/E#,"#Y0'+H.,H((/E2%"#Y41`@^4D((/E.""#Y4#` +M@^4\((/E+""#Y3`@@^4($(/E$!"#Y10`@^5P@+WH``"``&``@`!(8(``^/]_ +M```````P8(``$$`MZ61`G^7^___K8`"?Y6`0G^7^___K!`"@X0`PH.-0$)_E +M!#"`Y/[__^L$`*#A_O__ZT``G^5`$)_E0""?Y4`PG^7^___K`0IPXP!`H.$` +M``"*_O__ZRPPG^4``%3C``#@`P``H!-,0(/E$("]Z``````4`(``2&"````` +M`````(``N````+L```#X_W\```````0````$```````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````"PL+"`,````+"PL(!L````L+"P@-0```"PL+"`]````+"PL(`D`0`` +ML+"J@/0!``"PL*B`9`(``+"PKH`8!@``L+"J@.`&``"PL+"`\`8``+"PKH"P +M!P``L+"J@!`(``!?A`:`6`D``*\(L8`P"P``7X0$@,0-``"PL*J`;`X``+"P +MJ(!R:VYA;F1?8G5F9F5R+F,@=F5R"5X"@!B=68@9&%T +M82!S:7IE("`](#!X)7@*`%=R:71E(&-O=6YT("`](#!X)7@*`%)E860@8V]U +M;G0@(#T@,'@E>`H`1G)E92!C;W5N="`@/2`P>"5X"@!R:VYA;F1?8G5F9F5R +M7W1H!``N```` +M;````&@````2``$`M````-0````@````$@`!`,\```#T````,````!(``0#? +M````)`$``-`````2``$`\P``````````````$````/L``````````````!`` +M```#`0`````````````0````#`$`````````````$````!H!```````````` +M`!`````H`0`````````````0````+P$`````````````$````$`!```````` +M`````!````!'`0`````````````0````4`$`````````````$````&0!```` +M`````````!````!M`0`````````````0````=P$`````````````$````(L! +M`````````````!````"<`0`````````````0````N`$`````````````$``` +M`,$!```8!@``R````!(``0#;`0``X`8``!`````2``$`\@$````````````` +M$````/\!``#P!@``P````!(``0`2`@`````````````0````&0(``+`'``!@ +M````$@`!`#`"```0"```2`$``!(``0!$`@`````````````0````2P(````` +M````````$````%H"`````````````!````!L`@`````````````0````@@(` +M`%@)``#8`0``$@`!`)4"`````````````!````"E`@``,`L``)0"```2``$` +MMP(`````````````$````,\"`````````````!````#E`@``Q`T``*@````2 +M``$`_0(`````````````$`````<#``!L#@``D````!(``0`:`P`````````` +M```0````*0,````````G````$0`)`#\#````````#````!$``P!/`P`````` +M````@``1``4`80,`````@`!(8```$0`%``!R:VYA;F1?8G5F9F5R+F,`)&$` +M)&0`9&]?2XQ-3DV,`!R:VYA;F1?8G5F9F5R7VUE;5]I +M;FET`%]?865A8FE?=6YW:6YD7V-P<%]PF5R;P!R:VYA;F1?8G5F +M9F5R7VEN:70`:W1H= 0) { + bool seen; + + retval = request_irq(*irqp, el2_probe_interrupt, 0, + dev->name, &seen); + if (retval == -EBUSY) + continue; + if (retval < 0) + goto err_disable; + /* Twinkle the interrupt, and check if it's seen. */ - unsigned long cookie = probe_irq_on(); + seen = false; + smp_wmb(); outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR); outb_p(0x00, E33G_IDCFR); - if (*irqp == probe_irq_off(cookie) /* It's a good IRQ line! */ - && ((retval = request_irq(dev->irq = *irqp, - eip_interrupt, 0, dev->name, dev)) == 0)) - break; - } else { - if (retval != -EBUSY) - return retval; - } + msleep(1); + free_irq(*irqp, el2_probe_interrupt); + if (!seen) + continue; + + retval = request_irq(dev->irq = *irqp, eip_interrupt, 0, + dev->name, dev); + if (retval == -EBUSY) + continue; + if (retval < 0) + goto err_disable; } while (*++irqp); + if (*irqp == 0) { + err_disable: outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */ return -EAGAIN; } diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index dbf4de39754d..69698e504f3d 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -165,8 +165,8 @@ static struct pci_device_id com20020pci_id_table[] = { { 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, { 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, { 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, - { 0x10B5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, - { 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, + { 0x10B5, 0x9030, 0x10B5, 0x2978, 0, 0, ARC_CAN_10MBIT }, + { 0x10B5, 0x9050, 0x10B5, 0x2273, 0, 0, ARC_CAN_10MBIT }, { 0x14BA, 0x6000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, { 0x10B5, 0x2200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT }, {0,} diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c index 60edb9f232bb..b0fb7254e2cb 100644 --- a/drivers/net/atl1e/atl1e_ethtool.c +++ b/drivers/net/atl1e/atl1e_ethtool.c @@ -394,11 +394,13 @@ static const struct ethtool_ops atl1e_ethtool_ops = { .get_eeprom = atl1e_get_eeprom, .set_eeprom = atl1e_set_eeprom, .get_tx_csum = atl1e_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_hw_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, #ifdef NETIF_F_TSO .get_tso = ethtool_op_get_tso, #endif + .set_tso = ethtool_op_set_tso, }; void atl1e_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 00569dc1313c..403bfb6d13ee 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2856,10 +2856,11 @@ static int atl1_resume(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D3cold, 0); atl1_reset_hw(&adapter->hw); - adapter->cmb.cmb->int_stats = 0; - if (netif_running(netdev)) + if (netif_running(netdev)) { + adapter->cmb.cmb->int_stats = 0; atl1_up(adapter); + } netif_device_attach(netdev); return 0; diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 4869adb69586..137cb031df6c 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2175,8 +2175,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev, dev->irq = sdev->irq; SET_ETHTOOL_OPS(dev, &b44_ethtool_ops); - netif_carrier_off(dev); - err = ssb_bus_powerup(sdev->bus, 0); if (err) { dev_err(sdev->dev, @@ -2216,6 +2214,8 @@ static int __devinit b44_init_one(struct ssb_device *sdev, goto err_out_powerdown; } + netif_carrier_off(dev); + ssb_set_drvdata(sdev, dev); /* Chip reset provides power to the b44 MAC & PCI cores, which diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 08cddb6ff740..4874b2bd6bbd 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -247,6 +247,9 @@ static const struct flash_spec flash_5709 = { MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); +static void bnx2_init_napi(struct bnx2 *bp); +static void bnx2_del_napi(struct bnx2 *bp); + static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) { u32 diff; @@ -4752,8 +4755,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) rc = bnx2_alloc_bad_rbuf(bp); } - if (bp->flags & BNX2_FLAG_USING_MSIX) + if (bp->flags & BNX2_FLAG_USING_MSIX) { bnx2_setup_msix_tbl(bp); + /* Prevent MSIX table reads and write from timing out */ + REG_WR(bp, BNX2_MISC_ECO_HW_CTL, + BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN); + } return rc; } @@ -6169,6 +6176,7 @@ bnx2_open(struct net_device *dev) bnx2_disable_int(bp); bnx2_setup_int_mode(bp, disable_msi); + bnx2_init_napi(bp); bnx2_napi_enable(bp); rc = bnx2_alloc_mem(bp); if (rc) @@ -6230,6 +6238,7 @@ bnx2_open(struct net_device *dev) bnx2_free_skbs(bp); bnx2_free_irq(bp); bnx2_free_mem(bp); + bnx2_del_napi(bp); return rc; } @@ -6437,6 +6446,7 @@ bnx2_close(struct net_device *dev) bnx2_free_irq(bp); bnx2_free_skbs(bp); bnx2_free_mem(bp); + bnx2_del_napi(bp); bp->link_up = 0; netif_carrier_off(bp->dev); bnx2_set_power_state(bp, PCI_D3hot); @@ -8012,12 +8022,21 @@ bnx2_bus_string(struct bnx2 *bp, char *str) return str; } -static void __devinit +static void +bnx2_del_napi(struct bnx2 *bp) +{ + int i; + + for (i = 0; i < bp->irq_nvecs; i++) + netif_napi_del(&bp->bnx2_napi[i].napi); +} + +static void bnx2_init_napi(struct bnx2 *bp) { int i; - for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { + for (i = 0; i < bp->irq_nvecs; i++) { struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; int (*poll)(struct napi_struct *, int); @@ -8086,7 +8105,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->ethtool_ops = &bnx2_ethtool_ops; bp = netdev_priv(dev); - bnx2_init_napi(bp); pci_set_drvdata(pdev, dev); diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index c3fa31c9f2a7..d3854ac22cbf 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2451,6 +2451,9 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac if (!(dev->flags & IFF_MASTER)) goto out; + if (!pskb_may_pull(skb, sizeof(struct lacpdu))) + goto out; + read_lock(&bond->lock); slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev), orig_dev); diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 9b5936f072dc..71143751d8fd 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -370,6 +370,9 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct goto out; } + if (!pskb_may_pull(skb, arp_hdr_len(bond_dev))) + goto out; + if (skb->len < sizeof(struct arp_pkt)) { pr_debug("Packet is too small to be an ARP\n"); goto out; diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 16d2ecd2a3b7..9463e5db9566 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -84,6 +84,20 @@ static struct can_bittiming_const sja1000_bittiming_const = { .brp_inc = 1, }; +static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) +{ + unsigned long flags; + + /* + * The command register needs some locking and time to settle + * the write_reg() operation - especially on SMP systems. + */ + spin_lock_irqsave(&priv->cmdreg_lock, flags); + priv->write_reg(priv, REG_CMR, val); + priv->read_reg(priv, REG_SR); + spin_unlock_irqrestore(&priv->cmdreg_lock, flags); +} + static int sja1000_probe_chip(struct net_device *dev) { struct sja1000_priv *priv = netdev_priv(dev); @@ -279,7 +293,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, can_put_echo_skb(skb, dev, 0); - priv->write_reg(priv, REG_CMR, CMD_TR); + sja1000_write_cmdreg(priv, CMD_TR); return NETDEV_TX_OK; } @@ -334,7 +348,7 @@ static void sja1000_rx(struct net_device *dev) cf->data[i++] = 0; /* release receive buffer */ - priv->write_reg(priv, REG_CMR, CMD_RRB); + sja1000_write_cmdreg(priv, CMD_RRB); netif_rx(skb); @@ -368,7 +382,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; stats->rx_errors++; - priv->write_reg(priv, REG_CMR, CMD_CDO); /* clear bit */ + sja1000_write_cmdreg(priv, CMD_CDO); /* clear bit */ } if (isrc & IRQ_EI) { diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h index 302d2c763ad7..cfd3f57e4ab5 100644 --- a/drivers/net/can/sja1000/sja1000.h +++ b/drivers/net/can/sja1000/sja1000.h @@ -165,6 +165,7 @@ struct sja1000_priv { void __iomem *reg_base; /* ioremap'ed address to registers */ unsigned long irq_flags; /* for request_irq() */ + spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */ u16 flags; /* custom mode flags */ u8 ocr; /* output control register */ diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 61f9da2b4943..1cace005bff2 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1176,7 +1176,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) if (netif_msg_drv(priv)) printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(priv->phy); + rc = PTR_ERR(priv->phy); + goto fail; } if ((rc = register_netdev(dev))) { diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c index 5248f9e0b2f4..35cd36729155 100644 --- a/drivers/net/cxgb3/ael1002.c +++ b/drivers/net/cxgb3/ael1002.c @@ -934,7 +934,7 @@ static struct cphy_ops xaui_direct_ops = { int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { - cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, + cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, "10GBASE-CX4"); return 0; diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 34e776c5f06b..2b378e75b1b0 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1274,6 +1274,7 @@ static void cxgb_down(struct adapter *adapter) free_irq_resources(adapter); quiesce_rx(adapter); + t3_sge_stop(adapter); flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ } @@ -2274,6 +2275,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) case CHELSIO_GET_QSET_NUM:{ struct ch_reg edata; + memset(&edata, 0, sizeof(struct ch_reg)); + edata.cmd = CHELSIO_GET_QSET_NUM; edata.val = pi->nqsets; if (copy_to_user(useraddr, &edata, sizeof(edata))) diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 26ad04afe73e..f023d7b42ff9 100755 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -508,10 +508,9 @@ static uint32_t dm9000_get_rx_csum(struct net_device *dev) return dm->rx_csum; } -static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) +static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data) { board_info_t *dm = to_dm9000_board(dev); - unsigned long flags; if (dm->can_csum) { dm->rx_csum = data; @@ -529,6 +528,19 @@ static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) return -EOPNOTSUPP; } +static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) +{ + board_info_t *dm = to_dm9000_board(dev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&dm->lock, flags); + ret = dm9000_set_rx_csum_unlocked(dev, data); + spin_unlock_irqrestore(&dm->lock, flags); + + return ret; +} + static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data) { board_info_t *dm = to_dm9000_board(dev); @@ -707,7 +719,7 @@ static unsigned char dm9000_type_to_char(enum dm9000_type type) * Set DM9000 multicast address */ static void -dm9000_hash_table(struct net_device *dev) +dm9000_hash_table_unlocked(struct net_device *dev) { board_info_t *db = netdev_priv(dev); struct dev_mc_list *mcptr = dev->mc_list; @@ -716,14 +728,11 @@ dm9000_hash_table(struct net_device *dev) u32 hash_val; u16 hash_table[4]; u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN; - unsigned long flags; dm9000_dbg(db, 1, "entering %s\n", __func__); rk2818_nand_status_mutex_lock(); - spin_lock_irqsave(&db->lock, flags); - for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) iow(db, oft, dev->dev_addr[i]); @@ -753,6 +762,16 @@ dm9000_hash_table(struct net_device *dev) } iow(db, DM9000_RCR, rcr); +} + +static void +dm9000_hash_table(struct net_device *dev) +{ + board_info_t *db = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&db->lock, flags); + dm9000_hash_table_unlocked(dev); spin_unlock_irqrestore(&db->lock, flags); rk2818_nand_status_mutex_unlock(); @@ -773,7 +792,7 @@ dm9000_init_dm9000(struct net_device *dev) db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ /* Checksum mode */ - dm9000_set_rx_csum(dev, db->rx_csum); + dm9000_set_rx_csum_unlocked(dev, db->rx_csum); /* GPIO0 on pre-activate PHY */ iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ @@ -793,7 +812,7 @@ dm9000_init_dm9000(struct net_device *dev) iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */ /* Set address filter table */ - dm9000_hash_table(dev); + dm9000_hash_table_unlocked(dev); imr = IMR_PAR | IMR_PTM | IMR_PRM; if (db->type != TYPE_DM9000E) diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index aaea41ef794d..11f3b7c7422f 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -304,7 +304,7 @@ enum e1e_registers { #define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ #define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ #define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 -#define E1000_KMRNCTRLSTA_K1_ENABLE 0x140E +#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 #define E1000_KMRNCTRLSTA_K1_DISABLE 0x1400 #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 @@ -356,6 +356,7 @@ enum e1e_registers { #define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA #define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB +#define E1000_DEV_ID_ICH8_82567V_3 0x1501 #define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 #define E1000_DEV_ID_ICH8_IGP_AMT 0x104A #define E1000_DEV_ID_ICH8_IGP_C 0x104B diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index eff3f4783655..c688b55c1b75 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -3209,6 +3209,7 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) u32 phy_ctrl; switch (hw->mac.type) { + case e1000_ich8lan: case e1000_ich9lan: case e1000_ich10lan: case e1000_pchlan: diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 21545306bc1d..d177a02dd201 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -665,6 +665,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) i = 0; } + if (i == tx_ring->next_to_use) + break; eop = tx_ring->buffer_info[i].next_to_watch; eop_desc = E1000_TX_DESC(*tx_ring, eop); } @@ -3071,13 +3073,18 @@ static int e1000_test_msi(struct e1000_adapter *adapter) /* disable SERR in case the MSI write causes a master abort */ pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd); - pci_write_config_word(adapter->pdev, PCI_COMMAND, - pci_cmd & ~PCI_COMMAND_SERR); + if (pci_cmd & PCI_COMMAND_SERR) + pci_write_config_word(adapter->pdev, PCI_COMMAND, + pci_cmd & ~PCI_COMMAND_SERR); err = e1000_test_msi_interrupt(adapter); - /* restore previous setting of command word */ - pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd); + /* re-enable SERR */ + if (pci_cmd & PCI_COMMAND_SERR) { + pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd); + pci_cmd |= PCI_COMMAND_SERR; + pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd); + } /* success ! */ if (!err) @@ -5360,6 +5367,7 @@ static struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan }, diff --git a/drivers/net/eql.c b/drivers/net/eql.c index f5b96cadeb25..fd57fb421e91 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -554,6 +554,8 @@ static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mcp) equalizer_t *eql; master_config_t mc; + memset(&mc, 0, sizeof(master_config_t)); + if (eql_is_master(dev)) { eql = netdev_priv(dev); mc.max_slaves = eql->max_slaves; diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 3116601dbfea..7cd446d0f51a 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5900,7 +5900,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* Limit the number of tx's outstanding for hw bug */ if (id->driver_data & DEV_NEED_TX_LIMIT) { np->tx_limit = 1; - if ((id->driver_data & DEV_NEED_TX_LIMIT2) && + if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) && pci_dev->revision >= 0xA2) np->tx_limit = 0; } diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 5bf31f1509c9..934a28fde611 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1621,7 +1621,7 @@ static int gfar_clean_tx_ring(struct net_device *dev) if (skb_queue_len(&priv->rx_recycle) < priv->rx_ring_size && skb_recycle_check(skb, priv->rx_buffer_size + RXBUF_ALIGNMENT)) - __skb_queue_head(&priv->rx_recycle, skb); + skb_queue_head(&priv->rx_recycle, skb); else dev_kfree_skb_any(skb); @@ -1703,7 +1703,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev) struct gfar_private *priv = netdev_priv(dev); struct sk_buff *skb = NULL; - skb = __skb_dequeue(&priv->rx_recycle); + skb = skb_dequeue(&priv->rx_recycle); if (!skb) skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT); @@ -1862,7 +1862,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) * recycle list. */ skb->data = skb->head + NET_SKB_PAD; - __skb_queue_head(&priv->rx_recycle, skb); + skb_queue_head(&priv->rx_recycle, skb); } } else { /* Increment the number of packets */ diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index f8f5772557ce..33352ffa9669 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -81,6 +81,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) break; case E1000_DEV_ID_82576: case E1000_DEV_ID_82576_NS: + case E1000_DEV_ID_82576_NS_SERDES: case E1000_DEV_ID_82576_FIBER: case E1000_DEV_ID_82576_SERDES: case E1000_DEV_ID_82576_QUAD_COPPER: @@ -1167,9 +1168,18 @@ static s32 igb_read_mac_addr_82575(struct e1000_hw *hw) { s32 ret_val = 0; - if (igb_check_alt_mac_addr(hw)) - ret_val = igb_read_mac_addr(hw); + /* + * If there's an alternate MAC address place it in RAR0 + * so that it will override the Si installed default perm + * address. + */ + ret_val = igb_check_alt_mac_addr(hw); + if (ret_val) + goto out; + ret_val = igb_read_mac_addr(hw); + +out: return ret_val; } diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 119869b1124d..72081df3a397 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -42,6 +42,7 @@ struct e1000_hw; #define E1000_DEV_ID_82576_SERDES 0x10E7 #define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 #define E1000_DEV_ID_82576_NS 0x150A +#define E1000_DEV_ID_82576_NS_SERDES 0x1518 #define E1000_DEV_ID_82576_SERDES_QUAD 0x150D #define E1000_DEV_ID_82575EB_COPPER 0x10A7 #define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9 @@ -52,6 +53,8 @@ struct e1000_hw; #define E1000_FUNC_1 1 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 + enum e1000_mac_type { e1000_undefined = 0, e1000_82575, diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index 7d76bb085e10..d4fa82c45fb9 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c @@ -185,13 +185,12 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw) } if (nvm_alt_mac_addr_offset == 0xFFFF) { - ret_val = -(E1000_NOT_IMPLEMENTED); + /* There is no Alternate MAC Address */ goto out; } if (hw->bus.func == E1000_FUNC_1) - nvm_alt_mac_addr_offset += ETH_ALEN/sizeof(u16); - + nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; for (i = 0; i < ETH_ALEN; i += 2) { offset = nvm_alt_mac_addr_offset + (i >> 1); ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); @@ -206,14 +205,16 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw) /* if multicast bit is set, the alternate address will not be used */ if (alt_mac_addr[0] & 0x01) { - ret_val = -(E1000_NOT_IMPLEMENTED); + hw_dbg("Ignoring Alternate Mac Address with MC bit set\n"); goto out; } - for (i = 0; i < ETH_ALEN; i++) - hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i]; - - hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0); + /* + * We have a valid alternate MAC address, and we want to treat it the + * same as the normal permanent MAC address stored by the HW into the + * RAR. Do this by mapping this address into RAR0. + */ + hw->mac.ops.rar_set(hw, alt_mac_addr, 0); out: return ret_val; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 714c3a4a44ef..8111776927ae 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -63,6 +63,7 @@ static const struct e1000_info *igb_info_tbl[] = { static struct pci_device_id igb_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 }, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 34b04924c8a1..9c4214993b82 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -332,6 +332,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82599_KX4: case IXGBE_DEV_ID_82599_KX4_MEZZ: case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + case IXGBE_DEV_ID_82599_KR: case IXGBE_DEV_ID_82599_XAUI_LOM: /* Default device ID is mezzanine card KX/KX4 */ media_type = ixgbe_media_type_backplane; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a456578b8578..a873c5d7931a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -96,6 +96,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM), board_82599 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KR), + board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP), board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ), @@ -5239,9 +5241,13 @@ static int ixgbe_maybe_stop_tx(struct net_device *netdev, static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) { struct ixgbe_adapter *adapter = netdev_priv(dev); + int txq = smp_processor_id(); - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) - return smp_processor_id(); + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { + while (unlikely(txq >= dev->real_num_tx_queues)) + txq -= dev->real_num_tx_queues; + return txq; + } if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) return (skb->vlan_tci & IXGBE_TX_FLAGS_VLAN_PRIO_MASK) >> 13; diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index ef4bdd58e016..7d66f5bbbec9 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -50,6 +50,7 @@ #define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 #define IXGBE_DEV_ID_82599_KX4 0x10F7 #define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514 +#define IXGBE_DEV_ID_82599_KR 0x1517 #define IXGBE_DEV_ID_82599_CX4 0x10F9 #define IXGBE_DEV_ID_82599_SFP 0x10FB #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 1d2a32544ed2..a893f45db817 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -946,6 +946,8 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) jme->jme_vlan_rx(skb, jme->vlgrp, le16_to_cpu(rxdesc->descwb.vlan)); NET_STAT(jme).rx_bytes += 4; + } else { + dev_kfree_skb(skb); } } else { jme->jme_rx(skb); @@ -1576,6 +1578,16 @@ jme_free_irq(struct jme_adapter *jme) } } +static inline void +jme_phy_on(struct jme_adapter *jme) +{ + u32 bmcr; + + bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); + bmcr &= ~BMCR_PDOWN; + jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); +} + static int jme_open(struct net_device *netdev) { @@ -1596,10 +1608,12 @@ jme_open(struct net_device *netdev) jme_start_irq(jme); - if (test_bit(JME_FLAG_SSET, &jme->flags)) + if (test_bit(JME_FLAG_SSET, &jme->flags)) { + jme_phy_on(jme); jme_set_settings(netdev, &jme->old_ecmd); - else + } else { jme_reset_phy_processor(jme); + } jme_reset_link(jme); @@ -2085,12 +2099,45 @@ jme_tx_timeout(struct net_device *netdev) jme_reset_link(jme); } +static inline void jme_pause_rx(struct jme_adapter *jme) +{ + atomic_dec(&jme->link_changing); + + jme_set_rx_pcc(jme, PCC_OFF); + if (test_bit(JME_FLAG_POLL, &jme->flags)) { + JME_NAPI_DISABLE(jme); + } else { + tasklet_disable(&jme->rxclean_task); + tasklet_disable(&jme->rxempty_task); + } +} + +static inline void jme_resume_rx(struct jme_adapter *jme) +{ + struct dynpcc_info *dpi = &(jme->dpi); + + if (test_bit(JME_FLAG_POLL, &jme->flags)) { + JME_NAPI_ENABLE(jme); + } else { + tasklet_hi_enable(&jme->rxclean_task); + tasklet_hi_enable(&jme->rxempty_task); + } + dpi->cur = PCC_P1; + dpi->attempt = PCC_P1; + dpi->cnt = 0; + jme_set_rx_pcc(jme, PCC_P1); + + atomic_inc(&jme->link_changing); +} + static void jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { struct jme_adapter *jme = netdev_priv(netdev); + jme_pause_rx(jme); jme->vlgrp = grp; + jme_resume_rx(jme); } static void @@ -2978,10 +3025,12 @@ jme_resume(struct pci_dev *pdev) jme_clear_pm(jme); pci_restore_state(pdev); - if (test_bit(JME_FLAG_SSET, &jme->flags)) + if (test_bit(JME_FLAG_SSET, &jme->flags)) { + jme_phy_on(jme); jme_set_settings(netdev, &jme->old_ecmd); - else + } else { jme_reset_phy_processor(jme); + } jme_start_irq(jme); netif_device_attach(netdev); diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index c146304d8d6c..c0ceebccaa49 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -854,8 +854,8 @@ static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks) static irqreturn_t ks_irq(int irq, void *pw) { - struct ks_net *ks = pw; - struct net_device *netdev = ks->netdev; + struct net_device *netdev = pw; + struct ks_net *ks = netdev_priv(netdev); u16 status; /*this should be the first in IRQ handler */ diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c index 04b382fcb8c8..83eef8e35b76 100644 --- a/drivers/net/mlx4/icm.c +++ b/drivers/net/mlx4/icm.c @@ -174,10 +174,11 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, if (chunk->nsg <= 0) goto fail; - - chunk = NULL; } + if (chunk->npages == MLX4_ICM_CHUNK_LEN) + chunk = NULL; + npages -= 1 << cur_order; } else { --cur_order; diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 8a0904368e08..0f3ae462d431 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1199,7 +1199,6 @@ netxen_process_rcv(struct netxen_adapter *adapter, if (pkt_offset) skb_pull(skb, pkt_offset); - skb->truesize = skb->len + sizeof(struct sk_buff); skb->protocol = eth_type_trans(skb, netdev); napi_gro_receive(&sds_ring->napi, skb); @@ -1261,8 +1260,6 @@ netxen_process_lro(struct netxen_adapter *adapter, skb_put(skb, lro_length + data_offset); - skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); - skb_pull(skb, l2_hdr_offset); skb->protocol = eth_type_trans(skb, netdev); diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 5910df60c93e..b724d7faa3c8 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -1178,7 +1178,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Calculate UDP checksum if configured to do so */ if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT) skb->ip_summed = CHECKSUM_NONE; - else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { + else if ((skb_dst(skb) && skb_dst(skb)->dev) && + (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) { skb->ip_summed = CHECKSUM_COMPLETE; csum = skb_checksum(skb, 0, udp_len, 0); uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 8b14c6eda7c3..9ee9f01a929b 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -135,7 +135,7 @@ #define RX_DESC_SIZE (RX_DCNT * sizeof(struct r6040_descriptor)) #define TX_DESC_SIZE (TX_DCNT * sizeof(struct r6040_descriptor)) #define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ -#define MCAST_MAX 4 /* Max number multicast addresses to filter */ +#define MCAST_MAX 3 /* Max number multicast addresses to filter */ /* Descriptor status */ #define DSC_OWNER_MAC 0x8000 /* MAC is the owner of this descriptor */ @@ -985,9 +985,6 @@ static void r6040_multicast_list(struct net_device *dev) crc >>= 26; hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); } - /* Write the index of the hash table */ - for (i = 0; i < 4; i++) - iowrite16(hash_table[i] << 14, ioaddr + MCR1); /* Fill the MAC hash tables with their values */ iowrite16(hash_table[0], ioaddr + MAR0); iowrite16(hash_table[1], ioaddr + MAR1); @@ -995,6 +992,7 @@ static void r6040_multicast_list(struct net_device *dev) iowrite16(hash_table[3], ioaddr + MAR3); } /* Multicast Address 1~4 case */ + dmi = dev->mc_list; for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) { adrp = (u16 *)dmi->dmi_addr; iowrite16(adrp[0], ioaddr + MID_1L + 8*i); @@ -1003,9 +1001,9 @@ static void r6040_multicast_list(struct net_device *dev) dmi = dmi->next; } for (i = dev->mc_count; i < MCAST_MAX; i++) { - iowrite16(0xffff, ioaddr + MID_0L + 8*i); - iowrite16(0xffff, ioaddr + MID_0M + 8*i); - iowrite16(0xffff, ioaddr + MID_0H + 8*i); + iowrite16(0xffff, ioaddr + MID_1L + 8*i); + iowrite16(0xffff, ioaddr + MID_1M + 8*i); + iowrite16(0xffff, ioaddr + MID_1H + 8*i); } } diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0fe2fc90f207..7dd213239f2b 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -186,7 +186,12 @@ static struct pci_device_id rtl8169_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); -static int rx_copybreak = 200; +/* + * we set our copybreak very high so that we don't have + * to allocate 16k frames all the time (see note in + * rtl8169_open() + */ +static int rx_copybreak = 16383; static int use_dac; static struct { u32 msg_enable; @@ -552,6 +557,11 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value) break; udelay(25); } + /* + * According to hardware specs a 20us delay is required after write + * complete indication, but before sending next command. + */ + udelay(20); } static int mdio_read(void __iomem *ioaddr, int reg_addr) @@ -571,6 +581,12 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr) } udelay(25); } + /* + * According to hardware specs a 20us delay is required after read + * complete indication, but before sending next command. + */ + udelay(20); + return value; } @@ -2827,8 +2843,13 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) spin_lock_irq(&tp->lock); RTL_W8(Cfg9346, Cfg9346_Unlock); - RTL_W32(MAC0, low); + RTL_W32(MAC4, high); + RTL_R32(MAC4); + + RTL_W32(MAC0, low); + RTL_R32(MAC0); + RTL_W8(Cfg9346, Cfg9346_Lock); spin_unlock_irq(&tp->lock); @@ -3245,9 +3266,13 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) } static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, - struct net_device *dev) + unsigned int mtu) { - unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; + unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; + + if (max_frame != 16383) + printk(KERN_WARNING PFX "WARNING! Changing of MTU on this " + "NIC may lead to frame reception errors!\n"); tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; } @@ -3259,7 +3284,17 @@ static int rtl8169_open(struct net_device *dev) int retval = -ENOMEM; - rtl8169_set_rxbufsize(tp, dev); + /* + * Note that we use a magic value here, its wierd I know + * its done because, some subset of rtl8169 hardware suffers from + * a problem in which frames received that are longer than + * the size set in RxMaxSize register return garbage sizes + * when received. To avoid this we need to turn off filtering, + * which is done by setting a value of 16383 in the RxMaxSize register + * and allocating 16k frames to handle the largest possible rx value + * thats what the magic math below does. + */ + rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN); /* * Rx and Tx desscriptors needs 256 bytes alignment. @@ -3912,7 +3947,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) rtl8169_down(dev); - rtl8169_set_rxbufsize(tp, dev); + rtl8169_set_rxbufsize(tp, dev->mtu); ret = rtl8169_init_ring(dev); if (ret < 0) @@ -3964,7 +3999,7 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct net_device *dev, struct RxDesc *desc, int rx_buf_sz, - unsigned int align) + unsigned int align, gfp_t gfp) { struct sk_buff *skb; dma_addr_t mapping; @@ -3972,7 +4007,7 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, pad = align ? align : NET_IP_ALIGN; - skb = netdev_alloc_skb(dev, rx_buf_sz + pad); + skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp); if (!skb) goto err_out; @@ -4003,7 +4038,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) } static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, - u32 start, u32 end) + u32 start, u32 end, gfp_t gfp) { u32 cur; @@ -4018,7 +4053,7 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, tp->RxDescArray + i, - tp->rx_buf_sz, tp->align); + tp->rx_buf_sz, tp->align, gfp); if (!skb) break; @@ -4046,7 +4081,7 @@ static int rtl8169_init_ring(struct net_device *dev) memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); - if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC) + if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC) goto err_out; rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); @@ -4297,7 +4332,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->cur_tx += frags + 1; - smp_wmb(); + wmb(); RTL_W8(TxPoll, NPQ); /* set polling bit */ @@ -4549,7 +4584,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, count = cur_rx - tp->cur_rx; tp->cur_rx = cur_rx; - delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); + delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC); if (!delta && count && netif_msg_intr(tp)) printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name); tp->dirty_rx += delta; @@ -4657,7 +4692,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) * until it does. */ tp->intr_mask = 0xffff; - smp_wmb(); + wmb(); RTL_W16(IntrMask, tp->intr_event); } @@ -4795,8 +4830,8 @@ static void rtl_set_rx_mode(struct net_device *dev) mc_filter[1] = swab32(data); } - RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(MAR0 + 4, mc_filter[1]); + RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(RxConfig, tmp); diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 8f5414348e86..5b07e002f4e9 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "skge.h" @@ -3890,6 +3891,8 @@ static void __devinit skge_show_addr(struct net_device *dev) dev->name, dev->dev_addr); } +static int only_32bit_dma; + static int __devinit skge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -3911,7 +3914,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, pci_set_master(pdev); - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { using_dac = 1; err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { @@ -4168,8 +4171,21 @@ static struct pci_driver skge_driver = { .shutdown = skge_shutdown, }; +static struct dmi_system_id skge_32bit_dma_boards[] = { + { + .ident = "Gigabyte nForce boards", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"), + DMI_MATCH(DMI_BOARD_NAME, "nForce"), + }, + }, + {} +}; + static int __init skge_init_module(void) { + if (dmi_check_system(skge_32bit_dma_boards)) + only_32bit_dma = 1; skge_debug_init(); return pci_register_driver(&skge_driver); } diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f3600b3eb8c5..a17aaeed096c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -704,11 +704,24 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } +/* Enable Rx/Tx */ +static void sky2_enable_rx_tx(struct sky2_port *sky2) +{ + struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; + u16 reg; + + reg = gma_read16(hw, port, GM_GP_CTRL); + reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; + gma_write16(hw, port, GM_GP_CTRL, reg); +} + /* Force a renegotiation */ static void sky2_phy_reinit(struct sky2_port *sky2) { spin_lock_bh(&sky2->phy_lock); sky2_phy_init(sky2->hw, sky2->port); + sky2_enable_rx_tx(sky2); spin_unlock_bh(&sky2->phy_lock); } @@ -1008,11 +1021,8 @@ static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr, static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot) { struct sky2_tx_le *le = sky2->tx_le + *slot; - struct tx_ring_info *re = sky2->tx_ring + *slot; *slot = RING_NEXT(*slot, sky2->tx_ring_size); - re->flags = 0; - re->skb = NULL; le->ctrl = 0; return le; } @@ -1580,8 +1590,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) return count; } -static void sky2_tx_unmap(struct pci_dev *pdev, - const struct tx_ring_info *re) +static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re) { if (re->flags & TX_MAP_SINGLE) pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr), @@ -1591,6 +1600,7 @@ static void sky2_tx_unmap(struct pci_dev *pdev, pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr), pci_unmap_len(re, maplen), PCI_DMA_TODEVICE); + re->flags = 0; } /* @@ -1797,6 +1807,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; + re->skb = NULL; dev_kfree_skb_any(skb); sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size); @@ -1931,7 +1942,6 @@ static void sky2_link_up(struct sky2_port *sky2) { struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; - u16 reg; static const char *fc_name[] = { [FC_NONE] = "none", [FC_TX] = "tx", @@ -1939,10 +1949,7 @@ static void sky2_link_up(struct sky2_port *sky2) [FC_BOTH] = "both", }; - /* enable Rx/Tx */ - reg = gma_read16(hw, port, GM_GP_CTRL); - reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; - gma_write16(hw, port, GM_GP_CTRL, reg); + sky2_enable_rx_tx(sky2); gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index f9cdcbcb77d4..b496fa6811e8 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -85,8 +85,7 @@ struct smsc911x_data { */ spinlock_t mac_lock; - /* spinlock to ensure 16-bit accesses are serialised. - * unused with a 32-bit bus */ + /* spinlock to ensure register accesses are serialised */ spinlock_t dev_lock; struct phy_device *phy_dev; @@ -119,37 +118,33 @@ struct smsc911x_data { unsigned int hashlo; }; -/* The 16-bit access functions are significantly slower, due to the locking - * necessary. If your bus hardware can be configured to do this for you - * (in response to a single 32-bit operation from software), you should use - * the 32-bit access functions instead. */ - -static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) +static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) { if (pdata->config.flags & SMSC911X_USE_32BIT) return readl(pdata->ioaddr + reg); - if (pdata->config.flags & SMSC911X_USE_16BIT) { - u32 data; - 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) */ - spin_lock_irqsave(&pdata->dev_lock, flags); - data = ((readw(pdata->ioaddr + reg) & 0xFFFF) | + if (pdata->config.flags & SMSC911X_USE_16BIT) + return ((readw(pdata->ioaddr + reg) & 0xFFFF) | ((readw(pdata->ioaddr + reg + 2) & 0xFFFF) << 16)); - spin_unlock_irqrestore(&pdata->dev_lock, flags); - - return data; - } BUG(); return 0; } -static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, - u32 val) +static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) +{ + u32 data; + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + data = __smsc911x_reg_read(pdata, reg); + spin_unlock_irqrestore(&pdata->dev_lock, flags); + + return data; +} + +static inline void __smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, + u32 val) { if (pdata->config.flags & SMSC911X_USE_32BIT) { writel(val, pdata->ioaddr + reg); @@ -157,44 +152,54 @@ static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, } if (pdata->config.flags & SMSC911X_USE_16BIT) { - 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) */ - spin_lock_irqsave(&pdata->dev_lock, flags); writew(val & 0xFFFF, pdata->ioaddr + reg); writew((val >> 16) & 0xFFFF, pdata->ioaddr + reg + 2); - spin_unlock_irqrestore(&pdata->dev_lock, flags); return; } BUG(); } +static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, + u32 val) +{ + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + __smsc911x_reg_write(pdata, reg, val); + spin_unlock_irqrestore(&pdata->dev_lock, flags); +} + /* Writes a packet to the TX_DATA_FIFO */ static inline void smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf, unsigned int wordcount) { + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { while (wordcount--) - smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++)); - return; + __smsc911x_reg_write(pdata, TX_DATA_FIFO, + swab32(*buf++)); + goto out; } if (pdata->config.flags & SMSC911X_USE_32BIT) { writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount); - return; + goto out; } if (pdata->config.flags & SMSC911X_USE_16BIT) { while (wordcount--) - smsc911x_reg_write(pdata, TX_DATA_FIFO, *buf++); - return; + __smsc911x_reg_write(pdata, TX_DATA_FIFO, *buf++); + goto out; } BUG(); +out: + spin_unlock_irqrestore(&pdata->dev_lock, flags); } /* Reads a packet out of the RX_DATA_FIFO */ @@ -202,24 +207,31 @@ static inline void smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, unsigned int wordcount) { + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { while (wordcount--) - *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO)); - return; + *buf++ = swab32(__smsc911x_reg_read(pdata, + RX_DATA_FIFO)); + goto out; } if (pdata->config.flags & SMSC911X_USE_32BIT) { readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount); - return; + goto out; } if (pdata->config.flags & SMSC911X_USE_16BIT) { while (wordcount--) - *buf++ = smsc911x_reg_read(pdata, RX_DATA_FIFO); - return; + *buf++ = __smsc911x_reg_read(pdata, RX_DATA_FIFO); + goto out; } BUG(); +out: + spin_unlock_irqrestore(&pdata->dev_lock, flags); } /* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ba5d3fe753b6..fd6622ca4cd5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4995,7 +4995,7 @@ static void tg3_poll_controller(struct net_device *dev) struct tg3 *tp = netdev_priv(dev); for (i = 0; i < tp->irq_cnt; i++) - tg3_interrupt(tp->napi[i].irq_vec, dev); + tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]); } #endif @@ -5392,7 +5392,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, mss = 0; if ((mss = skb_shinfo(skb)->gso_size) != 0) { struct iphdr *iph; - int tcp_opt_len, ip_tcp_len, hdr_len; + u32 tcp_opt_len, ip_tcp_len, hdr_len; if (skb_header_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { @@ -5423,8 +5423,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, IPPROTO_TCP, 0); - if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) { + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) + mss |= hdr_len << 9; + else if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { if (tcp_opt_len || iph->ihl > 5) { int tsflags; @@ -5459,6 +5461,9 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, would_hit_hwbug = 0; + if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && len <= 8) + would_hit_hwbug = 1; + if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG) would_hit_hwbug = 1; else if (tg3_4g_overflow_test(mapping, len)) @@ -5482,6 +5487,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, tnapi->tx_buffers[entry].skb = NULL; + if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && + len <= 8) + would_hit_hwbug = 1; + if (tg3_4g_overflow_test(mapping, len)) would_hit_hwbug = 1; @@ -8159,6 +8168,7 @@ static int tg3_test_msi(struct tg3 *tp) pci_disable_msi(tp->pdev); tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; + tp->napi[0].irq_vec = tp->pdev->irq; err = tg3_request_irq(tp, 0); if (err) @@ -12608,6 +12618,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG; + tp->irq_max = 1; #ifdef TG3_NAPI @@ -13975,8 +13988,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_iounmap; } - if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) dev->netdev_ops = &tg3_netdev_ops; else dev->netdev_ops = &tg3_netdev_ops_dma_bug; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index bab7940158e6..529f55ad16db 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2759,6 +2759,9 @@ struct tg3 { #define TG3_FLG3_TOGGLE_10_100_L1PLLPD 0x00008000 #define TG3_FLG3_PHY_IS_FET 0x00010000 #define TG3_FLG3_ENABLE_RSS 0x00020000 +#define TG3_FLG3_4G_DMA_BNDRY_BUG 0x00080000 +#define TG3_FLG3_40BIT_DMA_LIMIT_BUG 0x00100000 +#define TG3_FLG3_SHORT_DMA_BUG 0x00200000 struct timer_list timer; u16 timer_counter; diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index 1cc8cf4425d1..516713fa0a05 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig @@ -101,6 +101,10 @@ config TULIP_NAPI_HW_MITIGATION If in doubt, say Y. +config TULIP_DM910X + def_bool y + depends on TULIP && SPARC + config DE4X5 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" depends on PCI || EISA diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index a45ded0538b8..b94370f7eb5a 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -92,6 +92,10 @@ #include #include +#ifdef CONFIG_TULIP_DM910X +#include +#endif + /* Board/System/Debug information/definition ---------------- */ #define PCI_DM9132_ID 0x91321282 /* Davicom DM9132 ID */ @@ -377,6 +381,23 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, if (!printed_version++) printk(version); + /* + * SPARC on-board DM910x chips should be handled by the main + * tulip driver, except for early DM9100s. + */ +#ifdef CONFIG_TULIP_DM910X + if ((ent->driver_data == PCI_DM9100_ID && pdev->revision >= 0x30) || + ent->driver_data == PCI_DM9102_ID) { + struct device_node *dp = pci_device_to_OF_node(pdev); + + if (dp && of_get_property(dp, "local-mac-address", NULL)) { + printk(KERN_INFO DRV_NAME + ": skipping on-board DM910x (use tulip)\n"); + return -ENODEV; + } + } +#endif + /* Init network device */ dev = alloc_etherdev(sizeof(*db)); if (dev == NULL) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 6b2330e4206e..88bf54f8562c 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -196,9 +196,13 @@ struct tulip_chip_table tulip_tbl[] = { | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task }, /* DM910X */ +#ifdef CONFIG_TULIP_DM910X { "Davicom DM9102/DM9102A", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer, tulip_media_task }, +#else + { NULL }, +#endif /* RS7112 */ { "Conexant LANfinity", 256, 0x0001ebef, @@ -228,8 +232,10 @@ static struct pci_device_id tulip_pci_tbl[] = { { 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 }, +#ifdef CONFIG_TULIP_DM910X { 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 }, @@ -1299,18 +1305,30 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, } /* - * Early DM9100's need software CRC and the DMFE driver + * DM910x chips should be handled by the dmfe driver, except + * on-board chips on SPARC systems. Also, early DM9100s need + * software CRC which only the dmfe driver supports. */ - if (pdev->vendor == 0x1282 && pdev->device == 0x9100) - { - /* Read Chip revision */ - if (pdev->revision < 0x30) - { - printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n"); +#ifdef CONFIG_TULIP_DM910X + if (chip_idx == DM910X) { + struct device_node *dp; + + if (pdev->vendor == 0x1282 && pdev->device == 0x9100 && + pdev->revision < 0x30) { + printk(KERN_INFO PFX + "skipping early DM9100 with Crc bug (use dmfe)\n"); + return -ENODEV; + } + + dp = pci_device_to_OF_node(pdev); + if (!(dp && of_get_property(dp, "local-mac-address", NULL))) { + printk(KERN_INFO PFX + "skipping DM910x expansion card (use dmfe)\n"); return -ENODEV; } } +#endif /* * Looks for early PCI chipsets where people report hangs diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 4fdfa2ae5418..0f77aca7280a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1006,7 +1006,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (err < 0) goto err_free_sk; - if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || + if (!net_eq(dev_net(tun->dev), &init_net) || + device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || device_create_file(&tun->dev->dev, &dev_attr_owner) || device_create_file(&tun->dev->dev, &dev_attr_group)) printk(KERN_ERR "Failed to create tun sysfs files\n"); diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 4469f2451a6f..b4b25ffa3ab7 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) static void ugeth_quiesce(struct ucc_geth_private *ugeth) { - /* Wait for and prevent any further xmits. */ + /* Prevent any further xmits, plus detach the device. */ + netif_device_detach(ugeth->ndev); + + /* Wait for any current xmits to finish. */ netif_tx_disable(ugeth->ndev); /* Disable the interrupt to avoid NAPI rescheduling. */ @@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) { napi_enable(&ugeth->napi); enable_irq(ugeth->ug_info->uf_info.irq); - netif_tx_wake_all_queues(ugeth->ndev); + netif_device_attach(ugeth->ndev); } /* Called every time the controller might need to be made @@ -3273,13 +3276,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + if (!skb) break; dev->stats.tx_packets++; - skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, ugeth->ug_info->uf_info.max_rx_buf_length + diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6ce7f775bb74..e644f9afa32a 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -54,6 +54,7 @@ static const char driver_name [] = "asix"; #define AX_CMD_WRITE_IPG0 0x12 #define AX_CMD_WRITE_IPG1 0x13 #define AX_CMD_READ_NODE_ID 0x13 +#define AX_CMD_WRITE_NODE_ID 0x14 #define AX_CMD_WRITE_IPG2 0x14 #define AX_CMD_WRITE_MULTI_FILTER 0x16 #define AX88172_CMD_READ_NODE_ID 0x17 @@ -165,6 +166,7 @@ static const char driver_name [] = "asix"; /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ struct asix_data { u8 multi_filter[AX_MCAST_FILTER_SIZE]; + u8 mac_addr[ETH_ALEN]; u8 phymode; u8 ledmode; u8 eeprom_len; @@ -728,6 +730,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); } +static int asix_set_mac_address(struct net_device *net, void *p) +{ + struct usbnet *dev = netdev_priv(net); + struct asix_data *data = (struct asix_data *)&dev->data; + struct sockaddr *addr = p; + + if (netif_running(net)) + return -EBUSY; + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); + + /* We use the 20 byte dev->data + * for our 6 byte mac buffer + * to avoid allocating memory that + * is tricky to free later */ + memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); + asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, + data->mac_addr); + + return 0; +} + /* We need to override some ethtool_ops so we require our own structure so we don't interfere with other usbnet devices that may be connected at the same time. */ @@ -915,7 +941,7 @@ static const struct net_device_ops ax88772_netdev_ops = { .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, .ndo_change_mtu = usbnet_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = asix_ioctl, .ndo_set_multicast_list = asix_set_multicast, @@ -1208,7 +1234,7 @@ static const struct net_device_ops ax88178_netdev_ops = { .ndo_stop = usbnet_stop, .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = asix_set_multicast, .ndo_do_ioctl = asix_ioctl, diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index a2b30a10064f..9a6eedef4afc 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -238,7 +238,7 @@ static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 valu goto out; dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg); - dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14); + dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12); for (i = 0; i < DM_TIMEOUT; i++) { u8 tmp; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 43bc3fcc0d85..f450bc9a89ac 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1634,6 +1634,8 @@ static int hso_get_count(struct hso_serial *serial, struct uart_icount cnow; struct hso_tiocmget *tiocmget = serial->tiocmget; + memset(&icount, 0, sizeof(struct serial_icounter_struct)); + if (!tiocmget) return -ENOENT; spin_lock_irq(&serial->serial_lock); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 1fd70583be44..31a5d3c15ae9 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -102,6 +102,7 @@ static const int multicast_filter_limit = 32; #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include @@ -389,6 +390,7 @@ struct rhine_private { struct net_device *dev; struct napi_struct napi; spinlock_t lock; + struct work_struct reset_task; /* Frequently used values: keep some adjacent for cache effect. */ u32 quirks; @@ -407,6 +409,7 @@ struct rhine_private { static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); static int rhine_open(struct net_device *dev); +static void rhine_reset_task(struct work_struct *work); static void rhine_tx_timeout(struct net_device *dev); static netdev_tx_t rhine_start_tx(struct sk_buff *skb, struct net_device *dev); @@ -775,6 +778,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, dev->irq = pdev->irq; spin_lock_init(&rp->lock); + INIT_WORK(&rp->reset_task, rhine_reset_task); + rp->mii_if.dev = dev; rp->mii_if.mdio_read = mdio_read; rp->mii_if.mdio_write = mdio_write; @@ -1179,22 +1184,18 @@ static int rhine_open(struct net_device *dev) return 0; } -static void rhine_tx_timeout(struct net_device *dev) +static void rhine_reset_task(struct work_struct *work) { - struct rhine_private *rp = netdev_priv(dev); - void __iomem *ioaddr = rp->base; - - printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " - "%4.4x, resetting...\n", - dev->name, ioread16(ioaddr + IntrStatus), - mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); + struct rhine_private *rp = container_of(work, struct rhine_private, + reset_task); + struct net_device *dev = rp->dev; /* protect against concurrent rx interrupts */ disable_irq(rp->pdev->irq); napi_disable(&rp->napi); - spin_lock(&rp->lock); + spin_lock_bh(&rp->lock); /* clear all descriptors */ free_tbufs(dev); @@ -1206,7 +1207,7 @@ static void rhine_tx_timeout(struct net_device *dev) rhine_chip_reset(dev); init_registers(dev); - spin_unlock(&rp->lock); + spin_unlock_bh(&rp->lock); enable_irq(rp->pdev->irq); dev->trans_start = jiffies; @@ -1214,6 +1215,19 @@ static void rhine_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } +static void rhine_tx_timeout(struct net_device *dev) +{ + struct rhine_private *rp = netdev_priv(dev); + void __iomem *ioaddr = rp->base; + + printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " + "%4.4x, resetting...\n", + dev->name, ioread16(ioaddr + IntrStatus), + mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); + + schedule_work(&rp->reset_task); +} + static netdev_tx_t rhine_start_tx(struct sk_buff *skb, struct net_device *dev) { @@ -1830,10 +1844,11 @@ static int rhine_close(struct net_device *dev) struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; - spin_lock_irq(&rp->lock); - - netif_stop_queue(dev); napi_disable(&rp->napi); + cancel_work_sync(&rp->reset_task); + netif_stop_queue(dev); + + spin_lock_irq(&rp->lock); if (debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard, " diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index e04e5bee005c..74b9d7d4a3ef 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2186,8 +2186,6 @@ static int velocity_open(struct net_device *dev) /* Ensure chip is running */ pci_set_power_state(vptr->pdev, PCI_D0); - velocity_give_many_rx_descs(vptr); - velocity_init_registers(vptr, VELOCITY_INIT_COLD); ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED, @@ -2199,6 +2197,8 @@ static int velocity_open(struct net_device *dev) goto out; } + velocity_give_many_rx_descs(vptr); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev); vptr->flags |= VELOCITY_FLAGS_OPENED; @@ -2287,10 +2287,10 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; - velocity_give_many_rx_descs(vptr); - velocity_init_registers(vptr, VELOCITY_INIT_COLD); + velocity_give_many_rx_descs(vptr); + mac_enable_int(vptr->mac_regs); netif_start_queue(dev); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b9e002fccbca..7e3788d54310 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -398,8 +398,7 @@ static void refill_work(struct work_struct *work) vi = container_of(work, struct virtnet_info, refill.work); napi_disable(&vi->napi); - try_fill_recv(vi, GFP_KERNEL); - still_empty = (vi->num == 0); + still_empty = !try_fill_recv(vi, GFP_KERNEL); napi_enable(&vi->napi); /* In theory, this can happen: if we don't get any buffers in diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index abf896a7390e..6c26840bfe0b 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5254,11 +5254,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key, WepKeyRid wkr; int rc; - if (keylen == 0) { - airo_print_err(ai->dev->name, "%s: key length to set was zero", - __func__); - return -1; - } + WARN_ON(keylen == 0); memset(&wkr, 0, sizeof(wkr)); wkr.len = cpu_to_le16(sizeof(wkr)); @@ -6404,11 +6400,7 @@ static int airo_set_encode(struct net_device *dev, if (dwrq->length > MIN_KEY_SIZE) key.len = MAX_KEY_SIZE; else - if (dwrq->length > 0) - key.len = MIN_KEY_SIZE; - else - /* Disable the key */ - key.len = 0; + key.len = MIN_KEY_SIZE; /* Check if the key is not marked as invalid */ if(!(dwrq->flags & IW_ENCODE_NOKEY)) { /* Cleanup */ @@ -6589,12 +6581,22 @@ static int airo_set_encodeext(struct net_device *dev, default: return -EINVAL; } - /* Send the key to the card */ - rc = set_wep_key(local, idx, key.key, key.len, perm, 1); - if (rc < 0) { - airo_print_err(local->dev->name, "failed to set WEP key" - " at index %d: %d.", idx, rc); - return rc; + if (key.len == 0) { + rc = set_wep_tx_idx(local, idx, perm, 1); + if (rc < 0) { + airo_print_err(local->dev->name, + "failed to set WEP transmit index to %d: %d.", + idx, rc); + return rc; + } + } else { + rc = set_wep_key(local, idx, key.key, key.len, perm, 1); + if (rc < 0) { + airo_print_err(local->dev->name, + "failed to set WEP key at index %d: %d.", + idx, rc); + return rc; + } } } diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 6cbfb2f83391..3931181f4d93 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h @@ -422,5 +422,6 @@ enum ar9170_txq { #define AR9170_TXQ_DEPTH 32 #define AR9170_TX_MAX_PENDING 128 +#define AR9170_RX_STREAM_MAX_SIZE 65535 #endif /* __AR9170_HW_H */ diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 509f378c3c21..a6514c1ffbbb 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -2526,7 +2526,7 @@ void *ar9170_alloc(size_t priv_size) * tends to split the streams into seperate rx descriptors. */ - skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); + skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL); if (!skb) goto err_nomem; diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index f141a4f711a1..dbcb72930fa3 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -66,18 +66,28 @@ static struct usb_device_id ar9170_usb_ids[] = { { USB_DEVICE(0x0cf3, 0x1001) }, /* TP-Link TL-WN821N v2 */ { USB_DEVICE(0x0cf3, 0x1002) }, + /* 3Com Dual Band 802.11n USB Adapter */ + { USB_DEVICE(0x0cf3, 0x1010) }, + /* H3C Dual Band 802.11n USB Adapter */ + { USB_DEVICE(0x0cf3, 0x1011) }, /* Cace Airpcap NX */ { USB_DEVICE(0xcace, 0x0300) }, /* D-Link DWA 160 A1 */ { USB_DEVICE(0x07d1, 0x3c10) }, /* D-Link DWA 160 A2 */ { USB_DEVICE(0x07d1, 0x3a09) }, + /* Netgear WNA1000 */ + { USB_DEVICE(0x0846, 0x9040) }, /* Netgear WNDA3100 */ { USB_DEVICE(0x0846, 0x9010) }, /* Netgear WN111 v2 */ { USB_DEVICE(0x0846, 0x9001) }, /* Zydas ZD1221 */ { USB_DEVICE(0x0ace, 0x1221) }, + /* Proxim ORiNOCO 802.11n USB */ + { USB_DEVICE(0x1435, 0x0804) }, + /* WNC Generic 11n USB Dongle */ + { USB_DEVICE(0x1435, 0x0326) }, /* ZyXEL NWD271N */ { USB_DEVICE(0x0586, 0x3417) }, /* Z-Com UB81 BG */ @@ -414,7 +424,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, spin_unlock_irqrestore(&aru->common.cmdlock, flags); usb_fill_int_urb(urb, aru->udev, - usb_sndbulkpipe(aru->udev, AR9170_EP_CMD), + usb_sndintpipe(aru->udev, AR9170_EP_CMD), aru->common.cmdbuf, plen + 4, ar9170_usb_tx_urb_complete, NULL, 1); diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 6cd5efcec417..2c79c78ef2d7 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -540,13 +540,12 @@ struct ath5k_txq_info { u32 tqi_cbr_period; /* Constant bit rate period */ u32 tqi_cbr_overflow_limit; u32 tqi_burst_time; - u32 tqi_ready_time; /* Not used */ + u32 tqi_ready_time; /* Time queue waits after an event */ }; /* * Transmit packet types. * used on tx control descriptor - * TODO: Use them inside base.c corectly */ enum ath5k_pkt_type { AR5K_PKT_TYPE_NORMAL = 0, diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 71a1bd254517..88663dfe3b3d 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -133,6 +133,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc) ah->ah_cw_min = AR5K_TUNE_CWMIN; ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; ah->ah_software_retry = false; + ah->ah_current_channel = &sc->channels[0]; /* * Find the mac version diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8a82c757ea63..2c4914a52789 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -448,6 +449,26 @@ ath5k_pci_probe(struct pci_dev *pdev, int ret; u8 csz; + /* + * L0s needs to be disabled on all ath5k cards. + * + * For distributions shipping with CONFIG_PCIEASPM (this will be enabled + * by default in the future in 2.6.36) this will also mean both L1 and + * L0s will be disabled when a pre 1.1 PCIe device is detected. We do + * know L1 works correctly even for all ath5k pre 1.1 PCIe devices + * though but cannot currently undue the effect of a blacklist, for + * details you can read pcie_aspm_sanity_check() and see how it adjusts + * the device link capability. + * + * It may be possible in the future to implement some PCI API to allow + * drivers to override blacklists for pre 1.1 PCIe but for now it is + * best to accept that both L0s and L1 will be disabled completely for + * distributions shipping with CONFIG_PCIEASPM rather than having this + * issue present. Motivation for adding this new API will be to help + * with power consumption for some of these devices. + */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "can't enable device\n"); @@ -1220,6 +1241,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) return 0; } +static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + enum ath5k_pkt_type htype; + __le16 fc; + + hdr = (struct ieee80211_hdr *)skb->data; + fc = hdr->frame_control; + + if (ieee80211_is_beacon(fc)) + htype = AR5K_PKT_TYPE_BEACON; + else if (ieee80211_is_probe_resp(fc)) + htype = AR5K_PKT_TYPE_PROBE_RESP; + else if (ieee80211_is_atim(fc)) + htype = AR5K_PKT_TYPE_ATIM; + else if (ieee80211_is_pspoll(fc)) + htype = AR5K_PKT_TYPE_PSPOLL; + else + htype = AR5K_PKT_TYPE_NORMAL; + + return htype; +} + static int ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, struct ath5k_txq *txq) @@ -1244,6 +1288,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, PCI_DMA_TODEVICE); rate = ieee80211_get_tx_rate(sc->hw, info); + if (!rate) { + ret = -EINVAL; + goto err_unmap; + } if (info->flags & IEEE80211_TX_CTL_NO_ACK) flags |= AR5K_TXDESC_NOACK; @@ -1274,7 +1322,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, sc->vif, pktlen, info)); } ret = ah->ah_setup_tx_desc(ah, ds, pktlen, - ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, + ieee80211_get_hdrlen_from_skb(skb), + get_hw_packet_type(skb), (sc->power_level * 2), hw_rate, info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, @@ -1487,7 +1536,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc) ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); if (ret) - return ret; + goto err; + if (sc->opmode == NL80211_IFTYPE_AP || sc->opmode == NL80211_IFTYPE_MESH_POINT) { /* @@ -1514,10 +1564,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc) if (ret) { ATH5K_ERR(sc, "%s: unable to update parameters for beacon " "hardware queue!\n", __func__); - return ret; + goto err; } + ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */ + if (ret) + goto err; - return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; + /* reconfigure cabq with ready time to 80% of beacon_interval */ + ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); + if (ret) + goto err; + + qi.tqi_ready_time = (sc->bintval * 80) / 100; + ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); + if (ret) + goto err; + + ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); +err: + return ret; } static void @@ -1778,11 +1843,6 @@ ath5k_tasklet_rx(unsigned long data) return; } - if (unlikely(rs.rs_more)) { - ATH5K_WARN(sc, "unsupported jumbo\n"); - goto next; - } - if (unlikely(rs.rs_status)) { if (rs.rs_status & AR5K_RXERR_PHY) goto next; @@ -1812,6 +1872,8 @@ ath5k_tasklet_rx(unsigned long data) sc->opmode != NL80211_IFTYPE_MONITOR) goto next; } + if (unlikely(rs.rs_more)) + goto next; accept: next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); @@ -2935,13 +2997,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { if (*new_flags & FIF_PROMISC_IN_BSS) { - rfilt |= AR5K_RX_FILTER_PROM; __set_bit(ATH_STAT_PROMISC, sc->status); } else { __clear_bit(ATH_STAT_PROMISC, sc->status); } } + if (test_bit(ATH_STAT_PROMISC, sc->status)) + rfilt |= AR5K_RX_FILTER_PROM; + /* Note, AR5K_RX_FILTER_MCAST is already enabled */ if (*new_flags & FIF_ALLMULTI) { mfilt[0] = ~0; diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index eeebb9aef206..b7c57259f134 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) break; case AR5K_TX_QUEUE_CAB: + /* XXX: use BCN_SENT_GT, if we can figure out how */ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_FRSHED_BCN_SENT_GT | + AR5K_QCU_MISC_FRSHED_DBA_GT | AR5K_QCU_MISC_CBREXP_DIS | AR5K_QCU_MISC_CBREXP_BCN_DIS); - ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - + ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) - AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 34e13c700849..257ea18c849f 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -1382,8 +1382,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * Set clocks to 32KHz operation and use an * external 32KHz crystal when sleeping if one * exists */ - if (ah->ah_version == AR5K_AR5212) - ath5k_hw_set_sleep_clock(ah, true); + if (ah->ah_version == AR5K_AR5212 && + ah->ah_op_mode != NL80211_IFTYPE_AP) + ath5k_hw_set_sleep_clock(ah, true); /* * Disable beacons and reset the register diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index cdb90c5bf39b..ad1196946c43 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -368,6 +368,7 @@ void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid, u16 *ssn); void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); +void ath9k_enable_ps(struct ath_softc *sc); /********/ /* VIFs */ diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 45c4ea57616b..72e24559ec4b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -512,16 +512,13 @@ static void ath_beacon_config_ap(struct ath_softc *sc, { u32 nexttbtt, intval; - /* Configure the timers only when the TSF has to be reset */ - - if (!(sc->sc_flags & SC_OP_TSF_RESET)) - return; - /* NB: the beacon interval is kept internally in TU's */ intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; intval /= ATH_BCBUF; /* for staggered beacons */ nexttbtt = intval; - intval |= ATH9K_BEACON_RESET_TSF; + + if (sc->sc_flags & SC_OP_TSF_RESET) + intval |= ATH9K_BEACON_RESET_TSF; /* * In AP mode we enable the beacon timers and SWBA interrupts to diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 4fe33f7eee9d..a5daa0d318cb 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -60,7 +60,7 @@ #define SD_NO_CTL 0xE0 #define NO_CTL 0xff -#define CTL_MODE_M 7 +#define CTL_MODE_M 0xf #define CTL_11A 0 #define CTL_11B 1 #define CTL_11G 2 diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 4071fc91da0a..95105782794c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -714,7 +714,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, vpdTableI[i][sizeCurrVpdTable - 2]); vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - if (tgtIndex > maxIndex) { + if (tgtIndex >= maxIndex) { while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 0905b38f7b62..aed75eb4d2b7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -398,7 +398,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.pcie_clock_req = 0; ah->config.pcie_waen = 0; ah->config.analog_shiftreg = 1; - ah->config.ht_enable = 1; ah->config.ofdm_trig_low = 200; ah->config.ofdm_trig_high = 500; ah->config.cck_trig_high = 200; @@ -412,6 +411,11 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.spurchans[i][1] = AR_NO_SPUR; } + if (ah->hw_version.devid != AR2427_DEVID_PCIE) + ah->config.ht_enable = 1; + else + ah->config.ht_enable = 0; + ah->config.intr_mitigation = true; /* @@ -617,6 +621,7 @@ static bool ath9k_hw_devid_supported(u16 devid) case AR9285_DEVID_PCIE: case AR5416_DEVID_AR9287_PCI: case AR5416_DEVID_AR9287_PCIE: + case AR2427_DEVID_PCIE: return true; default: break; @@ -924,7 +929,8 @@ int ath9k_hw_init(struct ath_hw *ah) if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - (AR_SREV_9280(ah) && !ah->is_pciexpress)) { + ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && + !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; } else { @@ -1295,6 +1301,16 @@ static void ath9k_hw_override_ini(struct ath_hw *ah, * Necessary to avoid issues on AR5416 2.0 */ REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); + + /* + * Disable RIFS search on some chips to avoid baseband + * hang issues. + */ + if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { + val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); + val &= ~AR_PHY_RIFS_INIT_DELAY; + REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); + } } static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, @@ -2387,7 +2403,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; /* For chips on which RTC reset is done, save TSF before it gets cleared */ - if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) + if (AR_SREV_9100(ah) || + (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) tsf = ath9k_hw_gettsf64(ah); saveLedState = REG_READ(ah, AR_CFG_LED) & @@ -2417,7 +2434,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } /* Restore TSF */ - if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) + if (tsf) ath9k_hw_settsf64(ah, tsf); if (AR_SREV_9280_10_OR_LATER(ah)) @@ -2437,6 +2454,17 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (r) return r; + /* + * Some AR91xx SoC devices frequently fail to accept TSF writes + * right after the chip reset. When that happens, write a new + * value after the initvals have been applied, with an offset + * based on measured time difference + */ + if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { + tsf += 1500; + ath9k_hw_settsf64(ah, tsf); + } + /* Setup MFP options for CCMP */ if (AR_SREV_9280_20_OR_LATER(ah)) { /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ff4383bb3ac3..262556ad62f2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -37,6 +37,7 @@ #define AR9280_DEVID_PCI 0x0029 #define AR9280_DEVID_PCIE 0x002a #define AR9285_DEVID_PCIE 0x002b +#define AR2427_DEVID_PCIE 0x002c #define AR5416_AR9100_DEVID 0x000b #define AR_SUBVENDOR_ID_NOG 0x0e11 #define AR_SUBVENDOR_ID_NEW_A 0x7065 diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h index 8622265a030a..a21c214a3e4d 100644 --- a/drivers/net/wireless/ath/ath9k/initvals.h +++ b/drivers/net/wireless/ath/ath9k/initvals.h @@ -2762,7 +2762,7 @@ static const u32 ar9280Common_9280_2[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, @@ -3935,7 +3935,7 @@ static const u_int32_t ar9285Common_9285[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, @@ -5072,7 +5072,7 @@ static const u_int32_t ar9287Common_9287_1_0[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, @@ -6864,7 +6864,7 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = { { 0x00008258, 0x00000000 }, { 0x0000825c, 0x400000ff }, { 0x00008260, 0x00080922 }, - { 0x00008264, 0xa8a00010 }, + { 0x00008264, 0x88a00010 }, { 0x00008270, 0x00000000 }, { 0x00008274, 0x40000000 }, { 0x00008278, 0x003e4180 }, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5864eaa53cfc..0c349cece951 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1538,14 +1538,19 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid) void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) { + struct ath_hw *ah = sc->sc_ah; + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SPECTRUM_MGMT; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) + hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; + if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) hw->flags |= IEEE80211_HW_MFP_CAPABLE; @@ -1555,7 +1560,10 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); - hw->wiphy->ps_default = false; + if (AR_SREV_5416(ah)) + hw->wiphy->ps_default = false; + else + hw->wiphy->ps_default = true; hw->queues = 4; hw->max_rates = 4; @@ -2305,6 +2313,19 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&sc->mutex); } +void ath9k_enable_ps(struct ath_softc *sc) +{ + sc->ps_enabled = true; + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { + if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { + sc->imask |= ATH9K_INT_TIM_TIMER; + ath9k_hw_set_interrupts(sc->sc_ah, + sc->imask); + } + } + ath9k_hw_setrxabort(sc->sc_ah, 1); +} + static int ath9k_config(struct ieee80211_hw *hw, u32 changed) { struct ath_wiphy *aphy = hw->priv; @@ -2336,19 +2357,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_PS) { if (conf->flags & IEEE80211_CONF_PS) { sc->sc_flags |= SC_OP_PS_ENABLED; - if (!(ah->caps.hw_caps & - ATH9K_HW_CAP_AUTOSLEEP)) { - if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { - sc->imask |= ATH9K_INT_TIM_TIMER; - ath9k_hw_set_interrupts(sc->sc_ah, - sc->imask); - } - } - sc->ps_enabled = true; if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) { sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; - sc->ps_enabled = true; - ath9k_hw_setrxabort(sc->sc_ah, 1); + ath9k_enable_ps(sc); } } else { sc->ps_enabled = false; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 903dd8ad9d43..14cf3fe95001 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -25,6 +25,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = { { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ + { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ { 0 } diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index dfda6f444648..b36ec9454460 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -368,6 +368,9 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 +#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC +#define AR_PHY_RIFS_INIT_DELAY 0x03ff0000 + #define AR_PHY_M_SLEEP 0x99f0 #define AR_PHY_REFCLKDLY 0x99f4 #define AR_PHY_REFCLKPD 0x99f8 diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 1895d63aad0a..fd397aa439c9 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -757,7 +757,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_tx_rate *rates = tx_info->control.rates; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 fc = hdr->frame_control; - u8 try_per_rate, i = 0, rix, nrix; + u8 try_per_rate, i = 0, rix; int is_probe = 0; if (rate_control_send_low(sta, priv_sta, txrc)) @@ -777,26 +777,25 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, rate_table = sc->cur_rate_table; rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); - nrix = rix; if (is_probe) { /* set one try for probe rates. For the * probes don't enable rts */ ath_rc_rate_set_series(rate_table, &rates[i++], txrc, - 1, nrix, 0); + 1, rix, 0); /* Get the next tried/allowed rate. No RTS for the next series * after the probe rate */ - ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); + ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); ath_rc_rate_set_series(rate_table, &rates[i++], txrc, - try_per_rate, nrix, 0); + try_per_rate, rix, 0); tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; } else { /* Set the choosen rate. No RTS for first series entry. */ ath_rc_rate_set_series(rate_table, &rates[i++], txrc, - try_per_rate, nrix, 0); + try_per_rate, rix, 0); } /* Fill in the other rates for multirate retry */ @@ -805,10 +804,10 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, if (i + 1 == 4) try_per_rate = 4; - ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); + ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); /* All other rates in the series have RTS enabled */ ath_rc_rate_set_series(rate_table, &rates[i], txrc, - try_per_rate, nrix, 1); + try_per_rate, rix, 1); } /* diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9009bac9207d..6a04681631d1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -423,6 +423,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, bf = bf_next; } + /* prepend un-acked frames to the beginning of the pending frame queue */ + if (!list_empty(&bf_pending)) { + spin_lock_bh(&txq->axq_lock); + list_splice(&bf_pending, &tid->buf_q); + ath_tx_queue_tid(txq, tid); + spin_unlock_bh(&txq->axq_lock); + } + if (tid->state & AGGR_CLEANUP) { if (tid->baw_head == tid->baw_tail) { tid->state &= ~AGGR_ADDBA_COMPLETE; @@ -435,14 +443,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, return; } - /* prepend un-acked frames to the beginning of the pending frame queue */ - if (!list_empty(&bf_pending)) { - spin_lock_bh(&txq->axq_lock); - list_splice(&bf_pending, &tid->buf_q); - ath_tx_queue_tid(txq, tid); - spin_unlock_bh(&txq->axq_lock); - } - rcu_read_unlock(); if (needreset) @@ -1320,25 +1320,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) return htype; } -static bool is_pae(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - if (ieee80211_is_data(fc)) { - if (ieee80211_is_nullfunc(fc) || - /* Port Access Entity (IEEE 802.1X) */ - (skb->protocol == cpu_to_be16(ETH_P_PAE))) { - return true; - } - } - - return false; -} - static int get_hw_crypto_keytype(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -1648,7 +1629,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, goto tx_done; } - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) { + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { /* * Try aggregation if it's a unicast data frame * and the destination is HT capable. @@ -1998,10 +1979,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (bf->bf_isnullfunc && (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { - if ((sc->sc_flags & SC_OP_PS_ENABLED)) { - sc->ps_enabled = true; - ath9k_hw_setrxabort(sc->sc_ah, 1); - } else + if ((sc->sc_flags & SC_OP_PS_ENABLED)) + ath9k_enable_ps(sc); + else sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED; } diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index c1dd857697a7..21cf5215f6f6 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h @@ -31,7 +31,6 @@ enum ctl_group { #define NO_CTL 0xff #define SD_NO_CTL 0xE0 #define NO_CTL 0xff -#define CTL_MODE_M 7 #define CTL_11A 0 #define CTL_11B 1 #define CTL_11G 2 diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 54ea61c15d8b..9da5373c3e59 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -78,11 +78,11 @@ config B43_SDIO If unsure, say N. -# Data transfers to the device via PIO -# This is only needed on PCMCIA and SDIO devices. All others can do DMA properly. +#Data transfers to the device via PIO. We want it as a fallback even +# if we can do DMA. config B43_PIO bool - depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO) + depends on B43 select SSB_BLOCKIO default y diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 84772a2542dc..5e83b6f0a3a0 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -12,7 +12,7 @@ b43-y += xmit.o b43-y += lo.o b43-y += wa.o b43-y += dma.o -b43-$(CONFIG_B43_PIO) += pio.o +b43-y += pio.o b43-y += rfkill.o b43-$(CONFIG_B43_LEDS) += leds.o b43-$(CONFIG_B43_PCMCIA) += pcmcia.o diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 0e6b15454d39..805d28a06ff5 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -696,6 +696,7 @@ struct b43_wldev { bool radio_hw_enable; /* saved state of radio hardware enabled state */ bool qos_enabled; /* TRUE, if QoS is used. */ bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ + bool use_pio; /* TRUE if next init should use PIO */ /* PHY/Radio device. */ struct b43_phy phy; @@ -750,12 +751,6 @@ struct b43_wldev { #endif }; -/* - * Include goes here to avoid a dependency problem. - * A better fix would be to integrate xmit.h into b43.h. - */ -#include "xmit.h" - /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */ struct b43_wl { /* Pointer to the active wireless device on this chip */ @@ -830,15 +825,9 @@ struct b43_wl { /* The device LEDs. */ struct b43_leds leds; -#ifdef CONFIG_B43_PIO - /* - * RX/TX header/tail buffers used by the frame transmit functions. - */ - struct b43_rxhdr_fw4 rxhdr; - struct b43_txhdr txhdr; - u8 rx_tail[4]; - u8 tx_tail[4]; -#endif /* CONFIG_B43_PIO */ + /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */ + u8 pio_scratchspace[110] __attribute__((__aligned__(8))); + u8 pio_tailspace[4] __attribute__((__aligned__(8))); }; static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) @@ -889,20 +878,15 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) static inline bool b43_using_pio_transfers(struct b43_wldev *dev) { -#ifdef CONFIG_B43_PIO return dev->__using_pio_transfers; -#else - return 0; -#endif } #ifdef CONFIG_B43_FORCE_PIO -# define B43_FORCE_PIO 1 +# define B43_PIO_DEFAULT 1 #else -# define B43_FORCE_PIO 0 +# define B43_PIO_DEFAULT 0 #endif - /* Message printing */ void b43info(struct b43_wl *wl, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index de4e804bedf0..571d475ca321 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1620,7 +1620,6 @@ void b43_dma_tx_resume(struct b43_wldev *dev) b43_power_saving_ctl_bits(dev, 0); } -#ifdef CONFIG_B43_PIO static void direct_fifo_rx(struct b43_wldev *dev, enum b43_dmatype type, u16 mmio_base, bool enable) { @@ -1654,4 +1653,3 @@ void b43_dma_direct_fifo_rx(struct b43_wldev *dev, mmio_base = b43_dmacontroller_base(type, engine_index); direct_fifo_rx(dev, type, mmio_base, enable); } -#endif /* CONFIG_B43_PIO */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 9ca253e40bd5..d6056347b6bd 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -102,6 +102,9 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; module_param_named(verbose, b43_modparam_verbose, int, 0644); MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); +int b43_modparam_pio = B43_PIO_DEFAULT; +module_param_named(pio, b43_modparam_pio, int, 0644); +MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), @@ -852,19 +855,16 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw, if (B43_WARN_ON(!modparam_hwtkip)) return; - mutex_lock(&wl->mutex); - + /* This is only called from the RX path through mac80211, where + * our mutex is already locked. */ + B43_WARN_ON(!mutex_is_locked(&wl->mutex)); dev = wl->current_dev; - if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) - goto out_unlock; + B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED); keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ rx_tkip_phase1_write(dev, index, iv32, phase1key); keymac_write(dev, index, addr); - -out_unlock: - mutex_unlock(&wl->mutex); } static void do_key_write(struct b43_wldev *dev, @@ -1791,6 +1791,10 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) dma_reason[0], dma_reason[1], dma_reason[2], dma_reason[3], dma_reason[4], dma_reason[5]); + b43err(dev->wl, "This device does not support DMA " + "on your system. Please use PIO instead.\n"); + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = 1; b43_controller_restart(dev, "DMA error"); return; } @@ -3967,6 +3971,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev) } /* We are ready to run. */ + ieee80211_wake_queues(dev->wl->hw); b43_set_status(dev, B43_STAT_STARTED); /* Start data flow (TX/RX). */ @@ -4357,7 +4362,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || - B43_FORCE_PIO) { + dev->use_pio) { dev->__using_pio_transfers = 1; err = b43_pio_init(dev); } else { @@ -4376,8 +4381,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev) ieee80211_wake_queues(dev->wl->hw); - ieee80211_wake_queues(dev->wl->hw); - b43_set_status(dev, B43_STAT_INITIALIZED); out: @@ -4827,6 +4830,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) if (!wldev) goto out; + wldev->use_pio = b43_modparam_pio; wldev->dev = dev; wldev->wl = wl; b43_set_status(wldev, B43_STAT_UNINIT); diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 9b9044400218..c5cd3bc861be 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c @@ -342,12 +342,15 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q, q->mmio_base + B43_PIO_TXDATA, sizeof(u16)); if (data_len & 1) { + u8 *tail = wl->pio_tailspace; + BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); + /* Write the last byte. */ ctl &= ~B43_PIO_TXCTL_WRITEHI; b43_piotx_write16(q, B43_PIO_TXCTL, ctl); - wl->tx_tail[0] = data[data_len - 1]; - wl->tx_tail[1] = 0; - ssb_block_write(dev->dev, wl->tx_tail, 2, + tail[0] = data[data_len - 1]; + tail[1] = 0; + ssb_block_write(dev->dev, tail, 2, q->mmio_base + B43_PIO_TXDATA, sizeof(u16)); } @@ -393,31 +396,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q, q->mmio_base + B43_PIO8_TXDATA, sizeof(u32)); if (data_len & 3) { - wl->tx_tail[3] = 0; + u8 *tail = wl->pio_tailspace; + BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); + + memset(tail, 0, 4); /* Write the last few bytes. */ ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31); switch (data_len & 3) { case 3: ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15; - wl->tx_tail[0] = data[data_len - 3]; - wl->tx_tail[1] = data[data_len - 2]; - wl->tx_tail[2] = data[data_len - 1]; + tail[0] = data[data_len - 3]; + tail[1] = data[data_len - 2]; + tail[2] = data[data_len - 1]; break; case 2: ctl |= B43_PIO8_TXCTL_8_15; - wl->tx_tail[0] = data[data_len - 2]; - wl->tx_tail[1] = data[data_len - 1]; - wl->tx_tail[2] = 0; + tail[0] = data[data_len - 2]; + tail[1] = data[data_len - 1]; break; case 1: - wl->tx_tail[0] = data[data_len - 1]; - wl->tx_tail[1] = 0; - wl->tx_tail[2] = 0; + tail[0] = data[data_len - 1]; break; } b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); - ssb_block_write(dev->dev, wl->tx_tail, 4, + ssb_block_write(dev->dev, tail, 4, q->mmio_base + B43_PIO8_TXDATA, sizeof(u32)); } @@ -456,6 +459,7 @@ static int pio_tx_frame(struct b43_pio_txqueue *q, int err; unsigned int hdrlen; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace; B43_WARN_ON(list_empty(&q->packets_list)); pack = list_entry(q->packets_list.next, @@ -463,7 +467,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q, cookie = generate_cookie(q, pack); hdrlen = b43_txhdr_size(dev); - err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb, + BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr)); + B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen); + err = b43_generate_txhdr(dev, (u8 *)txhdr, skb, info, cookie); if (err) return err; @@ -477,9 +483,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q, pack->skb = skb; if (q->rev >= 8) - pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); + pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen); else - pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); + pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen); /* Remove it from the list of available packet slots. * It will be put back when we receive the status report. */ @@ -625,8 +631,11 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q) unsigned int i, padding; struct sk_buff *skb; const char *err_msg = NULL; + struct b43_rxhdr_fw4 *rxhdr = + (struct b43_rxhdr_fw4 *)wl->pio_scratchspace; - memset(&wl->rxhdr, 0, sizeof(wl->rxhdr)); + BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(*rxhdr)); + memset(rxhdr, 0, sizeof(*rxhdr)); /* Check if we have data and wait for it to get ready. */ if (q->rev >= 8) { @@ -664,16 +673,16 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q) /* Get the preamble (RX header) */ if (q->rev >= 8) { - ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr), + ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); } else { - ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr), + ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); } /* Sanity checks. */ - len = le16_to_cpu(wl->rxhdr.frame_len); + len = le16_to_cpu(rxhdr->frame_len); if (unlikely(len > 0x700)) { err_msg = "len > 0x700"; goto rx_error; @@ -683,7 +692,7 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q) goto rx_error; } - macstat = le32_to_cpu(wl->rxhdr.mac_status); + macstat = le32_to_cpu(rxhdr->mac_status); if (macstat & B43_RX_MAC_FCSERR) { if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { /* Drop frames with failed FCS. */ @@ -708,22 +717,25 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q) q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); if (len & 3) { + u8 *tail = wl->pio_tailspace; + BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); + /* Read the last few bytes. */ - ssb_block_read(dev->dev, wl->rx_tail, 4, + ssb_block_read(dev->dev, tail, 4, q->mmio_base + B43_PIO8_RXDATA, sizeof(u32)); switch (len & 3) { case 3: - skb->data[len + padding - 3] = wl->rx_tail[0]; - skb->data[len + padding - 2] = wl->rx_tail[1]; - skb->data[len + padding - 1] = wl->rx_tail[2]; + skb->data[len + padding - 3] = tail[0]; + skb->data[len + padding - 2] = tail[1]; + skb->data[len + padding - 1] = tail[2]; break; case 2: - skb->data[len + padding - 2] = wl->rx_tail[0]; - skb->data[len + padding - 1] = wl->rx_tail[1]; + skb->data[len + padding - 2] = tail[0]; + skb->data[len + padding - 1] = tail[1]; break; case 1: - skb->data[len + padding - 1] = wl->rx_tail[0]; + skb->data[len + padding - 1] = tail[0]; break; } } @@ -732,15 +744,18 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q) q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); if (len & 1) { + u8 *tail = wl->pio_tailspace; + BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); + /* Read the last byte. */ - ssb_block_read(dev->dev, wl->rx_tail, 2, + ssb_block_read(dev->dev, tail, 2, q->mmio_base + B43_PIO_RXDATA, sizeof(u16)); - skb->data[len + padding - 1] = wl->rx_tail[0]; + skb->data[len + padding - 1] = tail[0]; } } - b43_rx(q->dev, skb, &wl->rxhdr); + b43_rx(q->dev, skb, rxhdr); return 1; diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h index 7dd649c9ddad..7b3c42f93a16 100644 --- a/drivers/net/wireless/b43/pio.h +++ b/drivers/net/wireless/b43/pio.h @@ -55,8 +55,6 @@ #define B43_PIO_MAX_NR_TXPACKETS 32 -#ifdef CONFIG_B43_PIO - struct b43_pio_txpacket { /* Pointer to the TX queue we belong to. */ struct b43_pio_txqueue *queue; @@ -169,42 +167,4 @@ void b43_pio_rx(struct b43_pio_rxqueue *q); void b43_pio_tx_suspend(struct b43_wldev *dev); void b43_pio_tx_resume(struct b43_wldev *dev); - -#else /* CONFIG_B43_PIO */ - - -static inline int b43_pio_init(struct b43_wldev *dev) -{ - return 0; -} -static inline void b43_pio_free(struct b43_wldev *dev) -{ -} -static inline void b43_pio_stop(struct b43_wldev *dev) -{ -} -static inline int b43_pio_tx(struct b43_wldev *dev, - struct sk_buff *skb) -{ - return 0; -} -static inline void b43_pio_handle_txstatus(struct b43_wldev *dev, - const struct b43_txstatus *status) -{ -} -static inline void b43_pio_get_tx_stats(struct b43_wldev *dev, - struct ieee80211_tx_queue_stats *stats) -{ -} -static inline void b43_pio_rx(struct b43_pio_rxqueue *q) -{ -} -static inline void b43_pio_tx_suspend(struct b43_wldev *dev) -{ -} -static inline void b43_pio_tx_resume(struct b43_wldev *dev) -{ -} - -#endif /* CONFIG_B43_PIO */ #endif /* B43_PIO_H_ */ diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index f4e9695ec186..51d68971f6fa 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -27,7 +27,7 @@ */ -#include "b43.h" +#include "xmit.h" #include "phy_common.h" #include "dma.h" #include "pio.h" diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 4b60148a5e61..c3968fad55e1 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2921,6 +2921,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev) goto out; } /* We are ready to run. */ + ieee80211_wake_queues(dev->wl->hw); b43legacy_set_status(dev, B43legacy_STAT_STARTED); /* Start data flow (TX/RX) */ @@ -3341,6 +3342,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) b43legacy_security_init(dev); b43legacy_rng_init(wl); + ieee80211_wake_queues(dev->wl->hw); b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); b43legacy_leds_init(dev); diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index ad8eab4a639b..b4ff1dc1d72d 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -626,6 +626,7 @@ static int prism2_config(struct pcmcia_device *link) int ret = 1; int last_fn, last_ret; struct hostap_cs_priv *hw_priv; + unsigned long flags; PDEBUG(DEBUG_FLOW, "prism2_config()\n"); @@ -660,6 +661,12 @@ static int prism2_config(struct pcmcia_device *link) strcpy(hw_priv->node.dev_name, dev->name); link->dev_node = &hw_priv->node; + /* + * Make sure the IRQ handler cannot proceed until at least + * dev->base_addr is initialized. + */ + spin_lock_irqsave(&local->irq_init_lock, flags); + /* * Allocate an interrupt line. Note that this does not assign a * handler to the interrupt, unless the 'Handler' member of the @@ -686,6 +693,8 @@ static int prism2_config(struct pcmcia_device *link) dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; + spin_unlock_irqrestore(&local->irq_init_lock, flags); + /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: ", dev_info, link->conf.ConfigIndex); @@ -715,6 +724,7 @@ static int prism2_config(struct pcmcia_device *link) return ret; cs_failed: + spin_unlock_irqrestore(&local->irq_init_lock, flags); cs_error(link, last_fn, last_ret); failed: diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index ff9b5c882184..2f999fc94f60 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -2621,6 +2621,18 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id) iface = netdev_priv(dev); local = iface->local; + /* Detect early interrupt before driver is fully configued */ + spin_lock(&local->irq_init_lock); + if (!dev->base_addr) { + if (net_ratelimit()) { + printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n", + dev->name); + } + spin_unlock(&local->irq_init_lock); + return IRQ_HANDLED; + } + spin_unlock(&local->irq_init_lock); + prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0); if (local->func->card_present && !local->func->card_present(local)) { @@ -3138,6 +3150,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, spin_lock_init(&local->cmdlock); spin_lock_init(&local->baplock); spin_lock_init(&local->lock); + spin_lock_init(&local->irq_init_lock); mutex_init(&local->rid_bap_mtx); if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES) diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c index 8fdd41f4b4f2..e131161137ae 100644 --- a/drivers/net/wireless/hostap/hostap_pci.c +++ b/drivers/net/wireless/hostap/hostap_pci.c @@ -329,6 +329,7 @@ static int prism2_pci_probe(struct pci_dev *pdev, dev->irq = pdev->irq; hw_priv->mem_start = mem; + dev->base_addr = (unsigned long) mem; prism2_pci_cor_sreset(local); diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 3d238917af07..1ba33be98b25 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -654,7 +654,7 @@ struct local_info { rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock * when removing entries from the list. * TX and RX paths can use read lock. */ - spinlock_t cmdlock, baplock, lock; + spinlock_t cmdlock, baplock, lock, irq_init_lock; struct mutex rid_bap_mtx; u16 infofid; /* MAC buffer id for info frame */ /* txfid, intransmitfid, next_txtid, and next_alloc are protected by diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 9d60f6cfa1d5..56bfcc35c9f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2545,11 +2545,9 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) memset((void *)&priv->hw_params, 0, sizeof(struct iwl_hw_params)); - priv->shared_virt = - pci_alloc_consistent(priv->pci_dev, - sizeof(struct iwl3945_shared), - &priv->shared_phys); - + priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev, + sizeof(struct iwl3945_shared), + &priv->shared_phys, GFP_KERNEL); if (!priv->shared_virt) { IWL_ERR(priv, "failed to allocate pci memory\n"); mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 99331edd9d75..585b8d49f35b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -715,6 +715,13 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); + /* make sure all queue are not stopped */ + memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); + for (i = 0; i < 4; i++) + atomic_set(&priv->queue_stop_count[i], 0); + + /* reset to 0 to enable all the queue first */ + priv->txq_ctx_active_msk = 0; /* Map each Tx/cmd queue to its corresponding fifo */ for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { int ac = default_queue_to_tx_fifo[i]; @@ -2134,7 +2141,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " "%d index %d\n", scd_ssn , index); freed = iwl_tx_queue_reclaim(priv, txq_id, index); - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + if (qc) + iwl_free_tfds_in_queue(priv, sta_id, + tid, freed); if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && @@ -2162,13 +2171,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, freed = iwl_tx_queue_reclaim(priv, txq_id, index); if (qc && likely(sta_id != IWL_INVALID_STATION)) - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + iwl_free_tfds_in_queue(priv, sta_id, tid, freed); + else if (sta_id == IWL_INVALID_STATION) + IWL_DEBUG_TX_REPLY(priv, "Station not known\n"); if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark)) iwl_wake_queue(priv, txq_id); } - if (qc && likely(sta_id != IWL_INVALID_STATION)) iwl_txq_check_empty(priv, sta_id, tid, txq_id); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 133df70bc609..1f423f2f6a25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -793,6 +793,13 @@ int iwl5000_alive_notify(struct iwl_priv *priv) iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); + /* make sure all queue are not stopped */ + memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); + for (i = 0; i < 4; i++) + atomic_set(&priv->queue_stop_count[i], 0); + + /* reset to 0 to enable all the queue first */ + priv->txq_ctx_active_msk = 0; /* map qos queues to fifos one-to-one */ for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { int ac = iwl5000_default_queue_to_tx_fifo[i]; @@ -1264,7 +1271,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, scd_ssn , index, txq_id, txq->swq_id); freed = iwl_tx_queue_reclaim(priv, txq_id, index); - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + iwl_free_tfds_in_queue(priv, sta_id, tid, freed); if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && @@ -1293,16 +1300,14 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, tx_resp->failure_frame); freed = iwl_tx_queue_reclaim(priv, txq_id, index); - if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + iwl_free_tfds_in_queue(priv, sta_id, tid, freed); if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark)) iwl_wake_queue(priv, txq_id); } - if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) - iwl_txq_check_empty(priv, sta_id, tid, txq_id); + iwl_txq_check_empty(priv, sta_id, tid, txq_id); if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); @@ -1669,12 +1674,12 @@ struct iwl_cfg iwl5300_agn_cfg = { .use_rts_for_ht = true, /* use rts/cts protection */ }; -struct iwl_cfg iwl5100_bg_cfg = { - .name = "5100BG", +struct iwl_cfg iwl5100_bgn_cfg = { + .name = "5100BGN", .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_G, + .sku = IWL_SKU_G|IWL_SKU_N, .ops = &iwl5000_ops, .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -1700,7 +1705,6 @@ struct iwl_cfg iwl5100_abg_cfg = { .valid_tx_ant = ANT_B, .valid_rx_ant = ANT_AB, .need_pll_cfg = true, - .ht_greenfield_support = true, }; struct iwl_cfg iwl5100_agn_cfg = { @@ -1757,6 +1761,22 @@ struct iwl_cfg iwl5150_agn_cfg = { .use_rts_for_ht = true, /* use rts/cts protection */ }; +struct iwl_cfg iwl5150_abg_cfg = { + .name = "5150ABG", + .fw_name_pre = IWL5150_FW_PRE, + .ucode_api_max = IWL5150_UCODE_API_MAX, + .ucode_api_min = IWL5150_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G, + .ops = &iwl5150_ops, + .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, + .eeprom_ver = EEPROM_5050_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, + .mod_params = &iwl50_mod_params, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, + .need_pll_cfg = true, +}; + MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 0eb25916f81d..1a3dfa2b1ef0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -402,10 +402,23 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, struct iwl_lq_sta *lq_data, u8 tid, struct ieee80211_sta *sta) { + int ret; + if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", sta->addr, tid); - ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); + ret = ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); + if (ret == -EAGAIN) { + /* + * driver and mac80211 is out of sync + * this might be cause by reloading firmware + * stop the tx ba session here + */ + IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n", + tid); + ret = ieee80211_stop_tx_ba_session(priv->hw, sta->addr, tid, + WLAN_BACK_INITIATOR); + } } } @@ -2180,9 +2193,12 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, /* Else we have enough samples; calculate estimate of * actual average throughput */ - - BUG_ON(window->average_tpt != ((window->success_ratio * - tbl->expected_tpt[index] + 64) / 128)); + if (window->average_tpt != ((window->success_ratio * + tbl->expected_tpt[index] + 64) / 128)) { + IWL_ERR(priv, "expected_tpt should have been calculated by now\n"); + window->average_tpt = ((window->success_ratio * + tbl->expected_tpt[index] + 64) / 128); + } /* If we are searching for better modulation mode, check success. */ if (lq_sta->search_better_tbl && diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 921dc4a26fe2..166bedd3c615 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3203,23 +3203,63 @@ static struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, #endif /* CONFIG_IWL4965 */ #ifdef CONFIG_IWL5000 - {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)}, - {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)}, - {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, - {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, - {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, - {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, - {IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)}, - {IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)}, - {IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)}, - {IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)}, -/* 5350 WiFi/WiMax */ - {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, - {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, - {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, -/* 5150 Wifi/WiMax */ - {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)}, - {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, +/* 5100 Series WiFi */ + {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ + +/* 5300 Series WiFi */ + {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ + +/* 5350 Series WiFi/WiMax */ + {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ + +/* 5150 Series Wifi/WiMax */ + {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ + + {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ + {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ /* 6000/6050 Series */ {IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)}, {IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)}, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 0cd4ec40a7d8..4a4f7e49a883 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1598,9 +1598,9 @@ EXPORT_SYMBOL(iwl_uninit_drv); void iwl_free_isr_ict(struct iwl_priv *priv) { if (priv->ict_tbl_vir) { - pci_free_consistent(priv->pci_dev, (sizeof(u32) * ICT_COUNT) + - PAGE_SIZE, priv->ict_tbl_vir, - priv->ict_tbl_dma); + dma_free_coherent(&priv->pci_dev->dev, + (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, + priv->ict_tbl_vir, priv->ict_tbl_dma); priv->ict_tbl_vir = NULL; } } @@ -1616,9 +1616,9 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv) if (priv->cfg->use_isr_legacy) return 0; /* allocate shrared data table */ - priv->ict_tbl_vir = pci_alloc_consistent(priv->pci_dev, (sizeof(u32) * - ICT_COUNT) + PAGE_SIZE, - &priv->ict_tbl_dma); + priv->ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev, + (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, + &priv->ict_tbl_dma, GFP_KERNEL); if (!priv->ict_tbl_vir) return -ENOMEM; @@ -2645,8 +2645,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) priv->staging_rxon.flags = 0; - iwl_set_rxon_ht(priv, ht_conf); iwl_set_rxon_channel(priv, conf->channel); + iwl_set_rxon_ht(priv, ht_conf); iwl_set_flags_for_band(priv, conf->channel->band); spin_unlock_irqrestore(&priv->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7754538c2194..40ec0c148d11 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -410,6 +410,8 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv); int iwl_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); +void iwl_free_tfds_in_queue(struct iwl_priv *priv, + int sta_id, int tid, int freed); int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index cea2ee25722c..3539ea4c9bd4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -53,9 +53,10 @@ extern struct iwl_cfg iwl4965_agn_cfg; extern struct iwl_cfg iwl5300_agn_cfg; extern struct iwl_cfg iwl5100_agn_cfg; extern struct iwl_cfg iwl5350_agn_cfg; -extern struct iwl_cfg iwl5100_bg_cfg; +extern struct iwl_cfg iwl5100_bgn_cfg; extern struct iwl_cfg iwl5100_abg_cfg; extern struct iwl_cfg iwl5150_agn_cfg; +extern struct iwl_cfg iwl5150_abg_cfg; extern struct iwl_cfg iwl6000h_2agn_cfg; extern struct iwl_cfg iwl6000i_2agn_cfg; extern struct iwl_cfg iwl6000_3agn_cfg; diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index bd0b12efb5c7..f8481e8bf04a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -80,8 +80,8 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) { if (desc->v_addr) - pci_free_consistent(pci_dev, desc->len, - desc->v_addr, desc->p_addr); + dma_free_coherent(&pci_dev->dev, desc->len, + desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; } @@ -89,7 +89,8 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) { - desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr); + desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, + &desc->p_addr, GFP_KERNEL); return (desc->v_addr != NULL) ? 0 : -ENOMEM; } diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 493626bcd3ec..3198a8a7633e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -345,10 +345,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) } } - pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->dma_addr); - pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), - rxq->rb_stts, rxq->rb_stts_dma); + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->dma_addr); + dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), + rxq->rb_stts, rxq->rb_stts_dma); rxq->bd = NULL; rxq->rb_stts = NULL; } @@ -357,7 +357,7 @@ EXPORT_SYMBOL(iwl_rx_queue_free); int iwl_rx_queue_alloc(struct iwl_priv *priv) { struct iwl_rx_queue *rxq = &priv->rxq; - struct pci_dev *dev = priv->pci_dev; + struct device *dev = &priv->pci_dev->dev; int i; spin_lock_init(&rxq->lock); @@ -365,12 +365,13 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) INIT_LIST_HEAD(&rxq->rx_used); /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ - rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); + rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr, + GFP_KERNEL); if (!rxq->bd) goto err_bd; - rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status), - &rxq->rb_stts_dma); + rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status), + &rxq->rb_stts_dma, GFP_KERNEL); if (!rxq->rb_stts) goto err_rb; @@ -387,8 +388,8 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) return 0; err_rb: - pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->dma_addr); + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->dma_addr); err_bd: return -ENOMEM; } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 4f3a108fa990..faa286ff6939 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -405,21 +405,6 @@ void iwl_init_scan_params(struct iwl_priv *priv) static int iwl_scan_initiate(struct iwl_priv *priv) { - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n"); - return -EIO; - } - - if (test_bit(STATUS_SCANNING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); - return -EAGAIN; - } - - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); - return -EAGAIN; - } - IWL_DEBUG_INFO(priv, "Starting scan...\n"); set_bit(STATUS_SCANNING, &priv->status); priv->scan_start = jiffies; @@ -450,6 +435,18 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, goto out_unlock; } + if (test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); + ret = -EAGAIN; + goto out_unlock; + } + + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); + ret = -EAGAIN; + goto out_unlock; + } + /* We don't schedule scan within next_scan_jiffies period. * Avoid scanning during possible EAPOL exchange, return * success immediately. @@ -500,11 +497,10 @@ void iwl_bg_scan_check(struct work_struct *data) return; mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status) || - test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting " - "adapter (%dms)\n", - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); + if (test_bit(STATUS_SCANNING, &priv->status) && + !test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n", + jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) iwl_send_scan_abort(priv); @@ -800,11 +796,11 @@ void iwl_bg_abort_scan(struct work_struct *work) !test_bit(STATUS_GEO_CONFIGURED, &priv->status)) return; + cancel_delayed_work(&priv->scan_check); + mutex_lock(&priv->mutex); - - set_bit(STATUS_SCAN_ABORTING, &priv->status); - iwl_send_scan_abort(priv); - + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) + iwl_send_scan_abort(priv); mutex_unlock(&priv->mutex); } EXPORT_SYMBOL(iwl_bg_abort_scan); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index b7e196e3c8d3..d21c06ea0ec3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -60,7 +60,8 @@ static const u16 default_tid_to_tx_fifo[] = { static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv, struct iwl_dma_ptr *ptr, size_t size) { - ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma); + ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma, + GFP_KERNEL); if (!ptr->addr) return -ENOMEM; ptr->size = size; @@ -73,7 +74,7 @@ static inline void iwl_free_dma_ptr(struct iwl_priv *priv, if (unlikely(!ptr->addr)) return; - pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma); + dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma); memset(ptr, 0, sizeof(*ptr)); } @@ -119,6 +120,20 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) EXPORT_SYMBOL(iwl_txq_update_write_ptr); +void iwl_free_tfds_in_queue(struct iwl_priv *priv, + int sta_id, int tid, int freed) +{ + if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) + priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + else { + IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", + priv->stations[sta_id].tid[tid].tfds_in_queue, + freed); + priv->stations[sta_id].tid[tid].tfds_in_queue = 0; + } +} +EXPORT_SYMBOL(iwl_free_tfds_in_queue); + /** * iwl_tx_queue_free - Deallocate DMA queue. * @txq: Transmit queue to deallocate. @@ -131,7 +146,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) { struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct iwl_queue *q = &txq->q; - struct pci_dev *dev = priv->pci_dev; + struct device *dev = &priv->pci_dev->dev; int i, len; if (q->n_bd == 0) @@ -150,8 +165,8 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) /* De-alloc circular buffer of TFDs */ if (txq->q.n_bd) - pci_free_consistent(dev, priv->hw_params.tfd_size * - txq->q.n_bd, txq->tfds, txq->q.dma_addr); + dma_free_coherent(dev, priv->hw_params.tfd_size * + txq->q.n_bd, txq->tfds, txq->q.dma_addr); /* De-alloc array of per-TFD driver data */ kfree(txq->txb); @@ -180,7 +195,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) { struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; struct iwl_queue *q = &txq->q; - struct pci_dev *dev = priv->pci_dev; + struct device *dev = &priv->pci_dev->dev; int i, len; if (q->n_bd == 0) @@ -195,8 +210,8 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) /* De-alloc circular buffer of TFDs */ if (txq->q.n_bd) - pci_free_consistent(dev, priv->hw_params.tfd_size * - txq->q.n_bd, txq->tfds, txq->q.dma_addr); + dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd, + txq->tfds, txq->q.dma_addr); /* deallocate arrays */ kfree(txq->cmd); @@ -287,7 +302,7 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, static int iwl_tx_queue_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq, u32 id) { - struct pci_dev *dev = priv->pci_dev; + struct device *dev = &priv->pci_dev->dev; size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; /* Driver private data, only for Tx (not command) queues, @@ -306,8 +321,8 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, /* Circular buffer of transmit frame descriptors (TFDs), * shared with device */ - txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr); - + txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, + GFP_KERNEL); if (!txq->tfds) { IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); goto error; @@ -776,8 +791,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr->seq_ctrl |= cpu_to_le16(seq_number); seq_number += 0x10; /* aggregation is on for this */ - if (info->flags & IEEE80211_TX_CTL_AMPDU) + if (info->flags & IEEE80211_TX_CTL_AMPDU && + priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) { txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; + } } txq = &priv->txq[txq_id]; @@ -1057,6 +1074,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) struct iwl_queue *q = &txq->q; struct iwl_tx_info *tx_info; int nfreed = 0; + struct ieee80211_hdr *hdr; if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " @@ -1071,13 +1089,16 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) tx_info = &txq->txb[txq->q.read_ptr]; ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); + + hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data; + if (hdr && ieee80211_is_data_qos(hdr->frame_control)) + nfreed++; tx_info->skb[0] = NULL; if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); priv->cfg->ops->lib->txq_free_tfd(priv, txq); - nfreed++; } return nfreed; } @@ -1254,7 +1275,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) { int tx_fifo_id, txq_id, sta_id, ssn = -1; struct iwl_tid_data *tid_data; - int ret, write_ptr, read_ptr; + int write_ptr, read_ptr; unsigned long flags; if (!ra) { @@ -1306,13 +1327,17 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; spin_lock_irqsave(&priv->lock, flags); - ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, + /* + * the only reason this call can fail is queue number out of range, + * which can happen if uCode is reloaded and all the station + * information are lost. if it is outside the range, there is no need + * to deactivate the uCode queue, just return "success" to allow + * mac80211 to clean up it own data. + */ + priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, tx_fifo_id); spin_unlock_irqrestore(&priv->lock, flags); - if (ret) - return ret; - ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid); return 0; @@ -1454,6 +1479,11 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, sta_id = ba_resp->sta_id; tid = ba_resp->tid; agg = &priv->stations[sta_id].tid[tid].agg; + if (unlikely(agg->txq_id != scd_flow)) { + IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n", + scd_flow, agg->txq_id); + return; + } /* Find index just before block-ack window */ index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); @@ -1485,7 +1515,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { /* calculate mac80211 ampdu sw queue to wake */ int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + iwl_free_tfds_in_queue(priv, sta_id, tid, freed); if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && priv->mac80211_registered && diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 5f26c93d3516..619590ddb096 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -356,10 +356,10 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) static void iwl3945_unset_hw_params(struct iwl_priv *priv) { if (priv->shared_virt) - pci_free_consistent(priv->pci_dev, - sizeof(struct iwl3945_shared), - priv->shared_virt, - priv->shared_phys); + dma_free_coherent(&priv->pci_dev->dev, + sizeof(struct iwl3945_shared), + priv->shared_virt, + priv->shared_phys); } static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, @@ -1272,10 +1272,10 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx } } - pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->dma_addr); - pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), - rxq->rb_stts, rxq->rb_stts_dma); + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->dma_addr); + dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), + rxq->rb_stts, rxq->rb_stts_dma); rxq->bd = NULL; rxq->rb_stts = NULL; } @@ -1904,7 +1904,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv, { int i; - for (i = 0; i < IWL_RATE_COUNT; i++) { + for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { rates[i].bitrate = iwl3945_rates[i].ieee * 5; rates[i].hw_value = i; /* Rate scaling will work on indexes */ rates[i].hw_value_short = i; diff --git a/drivers/net/wireless/libertas/if_sdio1.c b/drivers/net/wireless/libertas/if_sdio1.c index 90a47d35032a..2f45d6a3269a 100755 --- a/drivers/net/wireless/libertas/if_sdio1.c +++ b/drivers/net/wireless/libertas/if_sdio1.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "host.h" @@ -895,6 +896,7 @@ static int if_sdio_probe(struct sdio_func *func, int ret, i; unsigned int model; struct if_sdio_packet *packet; + struct mmc_host *host = func->card->host; lbs_deb_enter(LBS_DEB_SDIO); @@ -975,6 +977,25 @@ static int if_sdio_probe(struct sdio_func *func, if (ret) goto disable; + /* For 1-bit transfers to the 8686 model, we need to enable the + * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 + * bit to allow access to non-vendor registers. */ + if ((card->model == IF_SDIO_MODEL_8686) && + (host->caps & MMC_CAP_SDIO_IRQ) && + (host->ios.bus_width == MMC_BUS_WIDTH_1)) { + u8 reg; + + func->card->quirks |= MMC_QUIRK_LENIENT_FN0; + reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret); + if (ret) + goto release_int; + + reg |= SDIO_BUS_ECSI; + sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret); + if (ret) + goto release_int; + } + card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret); if (ret) goto release_int; diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 0efe67deedee..2c31eb4c21a2 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -126,7 +126,7 @@ static int p54_generate_band(struct ieee80211_hw *dev, int ret = -ENOMEM; if ((!list->entries) || (!list->band_channel_num[band])) - return 0; + return -EINVAL; tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); if (!tmp) @@ -158,6 +158,7 @@ static int p54_generate_band(struct ieee80211_hw *dev, (list->channels[i].data & CHAN_HAS_CURVE ? "" : " [curve data]"), list->channels[i].index, list->channels[i].freq); + continue; } tmp->channels[j].band = list->channels[i].band; @@ -165,7 +166,16 @@ static int p54_generate_band(struct ieee80211_hw *dev, j++; } - tmp->n_channels = list->band_channel_num[band]; + if (j == 0) { + printk(KERN_ERR "%s: Disabling totally damaged %s band.\n", + wiphy_name(dev->wiphy), (band == IEEE80211_BAND_2GHZ) ? + "2 GHz" : "5 GHz"); + + ret = -ENODATA; + goto err_out; + } + + tmp->n_channels = j; old = priv->band_table[band]; priv->band_table[band] = tmp; if (old) { @@ -228,13 +238,13 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) struct p54_common *priv = dev->priv; struct p54_channel_list *list; unsigned int i, j, max_channel_num; - int ret = -ENOMEM; + int ret = 0; u16 freq; if ((priv->iq_autocal_len != priv->curve_data->entries) || (priv->iq_autocal_len != priv->output_limit->entries)) - printk(KERN_ERR "%s: EEPROM is damaged... you may not be able" - "to use all channels with this device.\n", + printk(KERN_ERR "%s: Unsupported or damaged EEPROM detected. " + "You may not be able to use all channels.\n", wiphy_name(dev->wiphy)); max_channel_num = max_t(unsigned int, priv->output_limit->entries, @@ -243,14 +253,18 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) priv->curve_data->entries); list = kzalloc(sizeof(*list), GFP_KERNEL); - if (!list) + if (!list) { + ret = -ENOMEM; goto free; + } list->max_entries = max_channel_num; list->channels = kzalloc(sizeof(struct p54_channel_entry) * max_channel_num, GFP_KERNEL); - if (!list->channels) + if (!list->channels) { + ret = -ENOMEM; goto free; + } for (i = 0; i < max_channel_num; i++) { if (i < priv->iq_autocal_len) { @@ -282,13 +296,8 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) p54_compare_channels, NULL); for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) { - if (list->band_channel_num[i]) { - ret = p54_generate_band(dev, list, i); - if (ret) - goto free; - + if (p54_generate_band(dev, list, i) == 0) j++; - } } if (j == 0) { /* no useable band available. */ diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index d348c265e867..3df13f590182 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -40,6 +40,8 @@ static struct pci_device_id p54p_table[] __devinitdata = { { PCI_DEVICE(0x1260, 0x3877) }, /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */ { PCI_DEVICE(0x1260, 0x3886) }, + /* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */ + { PCI_DEVICE(0x1260, 0xffff) }, { }, }; @@ -157,6 +159,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev, skb_tail_pointer(skb), priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); + + if (pci_dma_mapping_error(priv->pdev, mapping)) { + dev_kfree_skb_any(skb); + dev_err(&priv->pdev->dev, + "RX DMA Mapping error\n"); + break; + } + desc->host_addr = cpu_to_le32(mapping); desc->device_addr = 0; // FIXME: necessary? desc->len = cpu_to_le16(priv->common.rx_mtu + 32); @@ -197,6 +207,14 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, i %= ring_limit; continue; } + + if (unlikely(len > priv->common.rx_mtu)) { + if (net_ratelimit()) + dev_err(&priv->pdev->dev, "rx'd frame size " + "exceeds length threshold.\n"); + + len = priv->common.rx_mtu; + } skb_put(skb, len); if (p54_rx(dev, skb)) { @@ -229,7 +247,7 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, u32 idx, i; i = (*index) % ring_limit; - (*index) = idx = le32_to_cpu(ring_control->device_idx[1]); + (*index) = idx = le32_to_cpu(ring_control->device_idx[ring_index]); idx %= ring_limit; while (i != idx) { @@ -317,14 +335,20 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) u32 device_idx, idx, i; spin_lock_irqsave(&priv->lock, flags); - device_idx = le32_to_cpu(ring_control->device_idx[1]); idx = le32_to_cpu(ring_control->host_idx[1]); i = idx % ARRAY_SIZE(ring_control->tx_data); - priv->tx_buf_data[i] = skb; mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(priv->pdev, mapping)) { + spin_unlock_irqrestore(&priv->lock, flags); + p54_free_skb(dev, skb); + dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); + return ; + } + priv->tx_buf_data[i] = skb; + desc = &ring_control->tx_data[i]; desc->host_addr = cpu_to_le32(mapping); desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 92af9b96bb7a..ab406c90172c 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -32,10 +32,20 @@ MODULE_ALIAS("prism54usb"); MODULE_FIRMWARE("isl3886usb"); MODULE_FIRMWARE("isl3887usb"); +/* + * Note: + * + * Always update our wiki's device list (located at: + * http://wireless.kernel.org/en/users/Drivers/p54/devices ), + * whenever you add a new device. + */ + static struct usb_device_id p54u_table[] __devinitdata = { /* Version 1 devices (pci chip + net2280) */ + {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ + {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */ {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */ @@ -44,7 +54,9 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ + {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ + {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ @@ -57,9 +69,11 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ + {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {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(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */ @@ -75,7 +89,9 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ + {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ + {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ {} @@ -926,8 +942,8 @@ static int __devinit p54u_probe(struct usb_interface *intf, #ifdef CONFIG_PM /* ISL3887 needs a full reset on resume */ udev->reset_resume = 1; +#endif /* CONFIG_PM */ err = p54u_device_reset(dev); -#endif priv->hw_type = P54U_3887; dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr); diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index b6dda2b27fb5..0edd7b493aa7 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -186,7 +186,7 @@ static int p54_tx_qos_accounting_alloc(struct p54_common *priv, struct ieee80211_tx_queue_stats *queue; unsigned long flags; - if (WARN_ON(p54_queue > P54_QUEUE_NUM)) + if (WARN_ON(p54_queue >= P54_QUEUE_NUM)) return -EINVAL; queue = &priv->tx_stats[p54_queue]; @@ -445,7 +445,7 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb) } if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (!payload->status)) + !(payload->status & P54_TX_FAILED)) info->flags |= IEEE80211_TX_STAT_ACK; if (payload->status & P54_TX_PSM_CANCELLED) info->flags |= IEEE80211_TX_STAT_TX_FILTERED; diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 54175b6fa86c..2ecbedb26e15 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -83,11 +83,11 @@ MODULE_PARM_DESC(roamdelta, "set roaming tendency: 0=aggressive, 1=moderate, " "2=conservative (default: moderate)"); -static int modparam_workaround_interval = 500; +static int modparam_workaround_interval; module_param_named(workaround_interval, modparam_workaround_interval, int, 0444); MODULE_PARM_DESC(workaround_interval, - "set stall workaround interval in msecs (default: 500)"); + "set stall workaround interval in msecs (0=disabled) (default: 0)"); /* various RNDIS OID defs */ @@ -733,12 +733,13 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) le32_to_cpu(u.get_c->status)); if (ret == 0) { + memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); + ret = le32_to_cpu(u.get_c->len); if (ret > *len) *len = ret; - memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); - ret = rndis_error_status(u.get_c->status); + ret = rndis_error_status(u.get_c->status); if (ret < 0) devdbg(dev, "rndis_query_oid(%s): device returned " "error, 0x%08x (%d)", oid_to_string(oid), @@ -1072,6 +1073,8 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version, auth_mode = NDIS_80211_AUTH_SHARED; else if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) auth_mode = NDIS_80211_AUTH_OPEN; + else if (auth_type == NL80211_AUTHTYPE_AUTOMATIC) + auth_mode = NDIS_80211_AUTH_AUTO_SWITCH; else return -ENOTSUPP; @@ -2547,7 +2550,7 @@ static void rndis_device_poller(struct work_struct *work) /* Workaround transfer stalls on poor quality links. * TODO: find right way to fix these stalls (as stalls do not happen * with ndiswrapper/windows driver). */ - if (priv->last_qual <= 25) { + if (priv->param_workaround_interval > 0 && priv->last_qual <= 25) { /* Decrease stats worker interval to catch stalls. * faster. Faster than 400-500ms causes packet loss, * Slower doesn't catch stalls fast enough. diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 16429c49139c..c6ca7ee16e84 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -190,6 +190,7 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) info->flags |= IEEE80211_TX_STAT_ACK; info->status.rates[0].count = (flags & 0xFF) + 1; + info->status.rates[1].idx = -1; ieee80211_tx_status_irqsafe(dev, skb); if (ring->entries - skb_queue_len(&ring->queue) == 2) diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c index a00723059f83..1685c09c8589 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c @@ -443,7 +443,8 @@ static int wl1251_debugfs_add_files(struct wl1251 *wl) void wl1251_debugfs_reset(struct wl1251 *wl) { - memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); + if (wl->stats.fw_stats != NULL) + memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); wl->stats.retry_count = 0; wl->stats.excessive_retries = 0; } diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index 9423f22bdced..d74b89bbda83 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c @@ -160,6 +160,7 @@ int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) sdio_disable_func(func); release: sdio_release_host(func); + wl1251_free_hw(wl); return ret; } diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index baa051d5bfbe..1a11d955f215 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1619,6 +1619,7 @@ static void backend_changed(struct xenbus_device *dev, if (xennet_connect(netdev) != 0) break; xenbus_switch_state(dev, XenbusStateConnected); + netif_notify_peers(netdev); break; case XenbusStateClosing: diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index c9e2ae90f195..5c4df24eae4b 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c @@ -140,16 +140,6 @@ static struct notifier_block module_load_nb = { .notifier_call = module_load_notify, }; - -static void end_sync(void) -{ - end_cpu_work(); - /* make sure we don't leak task structs */ - process_task_mortuary(); - process_task_mortuary(); -} - - int sync_start(void) { int err; @@ -157,7 +147,7 @@ int sync_start(void) if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) return -ENOMEM; - start_cpu_work(); + mutex_lock(&buffer_mutex); err = task_handoff_register(&task_free_nb); if (err) @@ -172,7 +162,10 @@ int sync_start(void) if (err) goto out4; + start_cpu_work(); + out: + mutex_unlock(&buffer_mutex); return err; out4: profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); @@ -181,7 +174,6 @@ int sync_start(void) out2: task_handoff_unregister(&task_free_nb); out1: - end_sync(); free_cpumask_var(marked_cpus); goto out; } @@ -189,11 +181,20 @@ int sync_start(void) void sync_stop(void) { + /* flush buffers */ + mutex_lock(&buffer_mutex); + end_cpu_work(); unregister_module_notifier(&module_load_nb); profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); task_handoff_unregister(&task_free_nb); - end_sync(); + mutex_unlock(&buffer_mutex); + flush_scheduled_work(); + + /* make sure we don't leak task structs */ + process_task_mortuary(); + process_task_mortuary(); + free_cpumask_var(marked_cpus); } diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index a7aae24f2889..5e2ac4aea949 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c @@ -30,23 +30,7 @@ #define OP_BUFFER_FLAGS 0 -/* - * Read and write access is using spin locking. Thus, writing to the - * buffer by NMI handler (x86) could occur also during critical - * sections when reading the buffer. To avoid this, there are 2 - * buffers for independent read and write access. Read access is in - * process context only, write access only in the NMI handler. If the - * read buffer runs empty, both buffers are swapped atomically. There - * is potentially a small window during swapping where the buffers are - * disabled and samples could be lost. - * - * Using 2 buffers is a little bit overhead, but the solution is clear - * and does not require changes in the ring buffer implementation. It - * can be changed to a single buffer solution when the ring buffer - * access is implemented as non-locking atomic code. - */ -static struct ring_buffer *op_ring_buffer_read; -static struct ring_buffer *op_ring_buffer_write; +static struct ring_buffer *op_ring_buffer; DEFINE_PER_CPU(struct oprofile_cpu_buffer, cpu_buffer); static void wq_sync_buffer(struct work_struct *work); @@ -69,12 +53,9 @@ void oprofile_cpu_buffer_inc_smpl_lost(void) void free_cpu_buffers(void) { - if (op_ring_buffer_read) - ring_buffer_free(op_ring_buffer_read); - op_ring_buffer_read = NULL; - if (op_ring_buffer_write) - ring_buffer_free(op_ring_buffer_write); - op_ring_buffer_write = NULL; + if (op_ring_buffer) + ring_buffer_free(op_ring_buffer); + op_ring_buffer = NULL; } #define RB_EVENT_HDR_SIZE 4 @@ -87,11 +68,8 @@ int alloc_cpu_buffers(void) unsigned long byte_size = buffer_size * (sizeof(struct op_sample) + RB_EVENT_HDR_SIZE); - op_ring_buffer_read = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS); - if (!op_ring_buffer_read) - goto fail; - op_ring_buffer_write = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS); - if (!op_ring_buffer_write) + op_ring_buffer = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS); + if (!op_ring_buffer) goto fail; for_each_possible_cpu(i) { @@ -143,8 +121,6 @@ void end_cpu_work(void) cancel_delayed_work(&b->work); } - - flush_scheduled_work(); } /* @@ -163,16 +139,11 @@ struct op_sample *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size) { entry->event = ring_buffer_lock_reserve - (op_ring_buffer_write, sizeof(struct op_sample) + + (op_ring_buffer, sizeof(struct op_sample) + size * sizeof(entry->sample->data[0])); - if (entry->event) - entry->sample = ring_buffer_event_data(entry->event); - else - entry->sample = NULL; - - if (!entry->sample) + if (!entry->event) return NULL; - + entry->sample = ring_buffer_event_data(entry->event); entry->size = size; entry->data = entry->sample->data; @@ -181,25 +152,16 @@ struct op_sample int op_cpu_buffer_write_commit(struct op_entry *entry) { - return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event); + return ring_buffer_unlock_commit(op_ring_buffer, entry->event); } struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu) { struct ring_buffer_event *e; - e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); - if (e) - goto event; - if (ring_buffer_swap_cpu(op_ring_buffer_read, - op_ring_buffer_write, - cpu)) + e = ring_buffer_consume(op_ring_buffer, cpu, NULL); + if (!e) return NULL; - e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL); - if (e) - goto event; - return NULL; -event: entry->event = e; entry->sample = ring_buffer_event_data(e); entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample)) @@ -210,8 +172,7 @@ struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu) unsigned long op_cpu_buffer_entries(int cpu) { - return ring_buffer_entries_cpu(op_ring_buffer_read, cpu) - + ring_buffer_entries_cpu(op_ring_buffer_write, cpu); + return ring_buffer_entries_cpu(op_ring_buffer, cpu); } static int diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 9581d3619450..cc31baa31659 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -182,16 +182,18 @@ static int led_proc_read(char *page, char **start, off_t off, int count, static int led_proc_write(struct file *file, const char *buf, unsigned long count, void *data) { - char *cur, lbuf[count + 1]; + char *cur, lbuf[32]; int d; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - memset(lbuf, 0, count + 1); + if (count >= sizeof(lbuf)) + count = sizeof(lbuf)-1; if (copy_from_user(lbuf, buf, count)) return -EFAULT; + lbuf[count] = 0; cur = lbuf; diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index c1abac8ab5c3..5becbdee4027 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void) int __init ibmphp_access_ebda (void) { - u8 format, num_ctlrs, rio_complete, hs_complete; + u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz; u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; int rc = 0; @@ -260,7 +260,16 @@ int __init ibmphp_access_ebda (void) iounmap (io_mem); debug ("returned ebda segment: %x\n", ebda_seg); - io_mem = ioremap(ebda_seg<<4, 1024); + io_mem = ioremap(ebda_seg<<4, 1); + if (!io_mem) + return -ENOMEM; + ebda_sz = readb(io_mem); + iounmap(io_mem); + debug("ebda size: %d(KiB)\n", ebda_sz); + if (ebda_sz == 0) + return -ENOMEM; + + io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024)); if (!io_mem ) return -ENOMEM; next_offset = 0x180; diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 2498602151e6..ba83495fb5a6 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -71,6 +71,49 @@ #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) +/* page table handling */ +#define LEVEL_STRIDE (9) +#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) + +static inline int agaw_to_level(int agaw) +{ + return agaw + 2; +} + +static inline int agaw_to_width(int agaw) +{ + return 30 + agaw * LEVEL_STRIDE; +} + +static inline int width_to_agaw(int width) +{ + return (width - 30) / LEVEL_STRIDE; +} + +static inline unsigned int level_to_offset_bits(int level) +{ + return (level - 1) * LEVEL_STRIDE; +} + +static inline int pfn_level_offset(unsigned long pfn, int level) +{ + return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; +} + +static inline unsigned long level_mask(int level) +{ + return -1UL << level_to_offset_bits(level); +} + +static inline unsigned long level_size(int level) +{ + return 1UL << level_to_offset_bits(level); +} + +static inline unsigned long align_to_level(unsigned long pfn, int level) +{ + return (pfn + level_size(level) - 1) & level_mask(level); +} /* VT-d pages must always be _smaller_ than MM pages. Otherwise things are never going to work. */ @@ -449,8 +492,6 @@ void free_iova_mem(struct iova *iova) } -static inline int width_to_agaw(int width); - static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) { unsigned long sagaw; @@ -664,51 +705,6 @@ static void free_context_table(struct intel_iommu *iommu) spin_unlock_irqrestore(&iommu->lock, flags); } -/* page table handling */ -#define LEVEL_STRIDE (9) -#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) - -static inline int agaw_to_level(int agaw) -{ - return agaw + 2; -} - -static inline int agaw_to_width(int agaw) -{ - return 30 + agaw * LEVEL_STRIDE; - -} - -static inline int width_to_agaw(int width) -{ - return (width - 30) / LEVEL_STRIDE; -} - -static inline unsigned int level_to_offset_bits(int level) -{ - return (level - 1) * LEVEL_STRIDE; -} - -static inline int pfn_level_offset(unsigned long pfn, int level) -{ - return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; -} - -static inline unsigned long level_mask(int level) -{ - return -1UL << level_to_offset_bits(level); -} - -static inline unsigned long level_size(int level) -{ - return 1UL << level_to_offset_bits(level); -} - -static inline unsigned long align_to_level(unsigned long pfn, int level) -{ - return (pfn + level_size(level) - 1) & level_mask(level); -} - static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, unsigned long pfn) { diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f9cf3173b23d..0fb1d0542339 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -195,6 +195,9 @@ void unmask_msi_irq(unsigned int irq) void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); + + BUG_ON(entry->dev->current_state != PCI_D0); + if (entry->msi_attrib.is_msix) { void __iomem *base = entry->mask_base + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; @@ -228,10 +231,32 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) read_msi_msg_desc(desc, msg); } +void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) +{ + struct msi_desc *entry = get_irq_desc_msi(desc); + + /* Assert that the cache is valid, assuming that + * valid messages are not all-zeroes. */ + BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | + entry->msg.data)); + + *msg = entry->msg; +} + +void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg) +{ + struct irq_desc *desc = irq_to_desc(irq); + + get_cached_msi_msg_desc(desc, msg); +} + void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); - if (entry->msi_attrib.is_msix) { + + if (entry->dev->current_state != PCI_D0) { + /* Don't touch the hardware now */ + } else if (entry->msi_attrib.is_msix) { void __iomem *base; base = entry->mask_base + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 0f6382f090ee..3a3b9110db3e 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -662,17 +662,21 @@ void pci_remove_legacy_files(struct pci_bus *b) #ifdef HAVE_PCI_MMAP -int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) +int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, + enum pci_mmap_api mmap_api) { - unsigned long nr, start, size; + unsigned long nr, start, size, pci_start; + if (pci_resource_len(pdev, resno) == 0) + return 0; nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; start = vma->vm_pgoff; size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; - if (start < size && size - start >= nr) + pci_start = (mmap_api == PCI_MMAP_PROCFS) ? + pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; + if (start >= pci_start && start < pci_start + size && + start + nr <= pci_start + size) return 1; - WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", - current->comm, start, start+nr, pci_name(pdev), resno, size); return 0; } @@ -702,8 +706,14 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, if (i >= PCI_ROM_RESOURCE) return -ENODEV; - if (!pci_mmap_fits(pdev, i, vma)) + if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) { + WARN(1, "process \"%s\" tried to map 0x%08lx bytes " + "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n", + current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff, + pci_name(pdev), i, + pci_resource_start(pdev, i), pci_resource_len(pdev, i)); return -EINVAL; + } /* pci_mmap_page_range() expects the same kind of entry as coming * from /proc/bus/pci/ which is a "user visible" value. If this is diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 64777220a719..812d4ac6bd2f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -601,7 +601,7 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) */ int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) { - return state > PCI_D0 ? + return state >= PCI_D0 ? pci_platform_power_transition(dev, state) : -EINVAL; } EXPORT_SYMBOL_GPL(__pci_complete_power_transition); @@ -638,10 +638,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) */ return 0; - /* Check if we're already there */ - if (dev->current_state == state) - return 0; - __pci_start_power_transition(dev, state); /* This device is quirked not to be put into D3, so @@ -2050,6 +2046,7 @@ void pci_msi_off(struct pci_dev *dev) pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); } } +EXPORT_SYMBOL_GPL(pci_msi_off); #ifndef HAVE_ARCH_PCI_SET_DMA_MASK /* @@ -2350,18 +2347,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function); */ int pcix_get_max_mmrbc(struct pci_dev *dev) { - int err, cap; + int cap; u32 stat; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) return -EINVAL; - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); - if (err) + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) return -EINVAL; - return (stat & PCI_X_STATUS_MAX_READ) >> 12; + return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); } EXPORT_SYMBOL(pcix_get_max_mmrbc); @@ -2374,18 +2370,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); */ int pcix_get_mmrbc(struct pci_dev *dev) { - int ret, cap; - u32 cmd; + int cap; + u16 cmd; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) return -EINVAL; - ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); - if (!ret) - ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) + return -EINVAL; - return ret; + return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); } EXPORT_SYMBOL(pcix_get_mmrbc); @@ -2400,28 +2395,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc); */ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) { - int cap, err = -EINVAL; - u32 stat, cmd, v, o; + int cap; + u32 stat, v, o; + u16 cmd; if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) - goto out; + return -EINVAL; v = ffs(mmrbc) - 10; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) - goto out; + return -EINVAL; - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); - if (err) - goto out; + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) + return -EINVAL; if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) return -E2BIG; - err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); - if (err) - goto out; + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) + return -EINVAL; o = (cmd & PCI_X_CMD_MAX_READ) >> 2; if (o != v) { @@ -2431,10 +2425,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) cmd &= ~PCI_X_CMD_MAX_READ; cmd |= v << 2; - err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); + if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd)) + return -EIO; } -out: - return err; + return 0; } EXPORT_SYMBOL(pcix_set_mmrbc); @@ -2544,6 +2538,23 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) return 0; } +/* Some architectures require additional programming to enable VGA */ +static arch_set_vga_state_t arch_set_vga_state; + +void __init pci_register_set_vga_state(arch_set_vga_state_t func) +{ + arch_set_vga_state = func; /* NULL disables */ +} + +static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode, + unsigned int command_bits, bool change_bridge) +{ + if (arch_set_vga_state) + return arch_set_vga_state(dev, decode, command_bits, + change_bridge); + return 0; +} + /** * pci_set_vga_state - set VGA decode state on device and parents if requested * @dev: the PCI device @@ -2557,9 +2568,15 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, struct pci_bus *bus; struct pci_dev *bridge; u16 cmd; + int rc; WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); + /* ARCH specific VGA enables */ + rc = pci_set_vga_state_arch(dev, decode, command_bits, change_bridge); + if (rc) + return rc; + pci_read_config_word(dev, PCI_COMMAND, &cmd); if (decode == true) cmd |= command_bits; @@ -2806,4 +2823,3 @@ EXPORT_SYMBOL(pci_target_state); EXPORT_SYMBOL(pci_prepare_to_sleep); EXPORT_SYMBOL(pci_back_from_sleep); EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); - diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d92d1954a2fb..bfc3337adcd1 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -13,8 +13,13 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_cleanup_rom(struct pci_dev *dev); #ifdef HAVE_PCI_MMAP +enum pci_mmap_api { + PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices//resource */ + PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/ */ +}; extern int pci_mmap_fits(struct pci_dev *pdev, int resno, - struct vm_area_struct *vma); + struct vm_area_struct *vmai, + enum pci_mmap_api mmap_api); #endif int pci_probe_reset_function(struct pci_dev *dev); diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 0d91a8a4d278..b8fb987e7600 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -302,7 +302,7 @@ static int aer_inject(struct aer_error_inj *einj) unsigned long flags; unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); int pos_cap_err, rp_pos_cap_err; - u32 sever; + u32 sever, cor_mask, uncor_mask; int ret = 0; dev = pci_get_bus_and_slot(einj->bus, devfn); @@ -320,6 +320,9 @@ static int aer_inject(struct aer_error_inj *einj) goto out_put; } pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); + pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask); + pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, + &uncor_mask); rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); if (!rp_pos_cap_err) { @@ -354,6 +357,21 @@ static int aer_inject(struct aer_error_inj *einj) err->header_log2 = einj->header_log2; err->header_log3 = einj->header_log3; + if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { + ret = -EINVAL; + printk(KERN_WARNING "The correctable error(s) is masked " + "by device\n"); + spin_unlock_irqrestore(&inject_lock, flags); + goto out_put; + } + if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { + ret = -EINVAL; + printk(KERN_WARNING "The uncorrectable error(s) is masked " + "by device\n"); + spin_unlock_irqrestore(&inject_lock, flags); + goto out_put; + } + rperr = __find_aer_error_by_dev(rpdev); if (!rperr) { rperr = rperr_alloc; diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 9f5ccbeb4fa5..72fa87c095d8 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -78,19 +78,15 @@ EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) { int pos; - u32 status, mask; + u32 status; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return -EIO; pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); - if (dev->error_state == pci_channel_io_normal) - status &= ~mask; /* Clear corresponding nonfatal bits */ - else - status &= mask; /* Clear corresponding fatal bits */ - pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); + if (status) + pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); return 0; } diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 593bb844b8db..a03ad8cfc6b9 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -259,7 +259,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) /* Make sure the caller is mapping a real resource for this device */ for (i = 0; i < PCI_ROM_RESOURCE; i++) { - if (pci_mmap_fits(dev, i, vma)) + if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS)) break; } diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 245d2cdb4765..4633fc228603 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -154,6 +154,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_d DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); +/* + * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear + * for some HT machines to use C4 w/o hanging. + */ +static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev) +{ + u32 pmbase; + u16 pm1a; + + pci_read_config_dword(dev, 0x40, &pmbase); + pmbase = pmbase & 0xff80; + pm1a = inw(pmbase); + + if (pm1a & 0x10) { + dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n"); + outw(0x10, pmbase); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts); + /* * Chipsets where PCI->PCI transfers vanish or hang */ @@ -1444,7 +1464,8 @@ static void quirk_jmicron_ata(struct pci_dev *pdev) conf5 &= ~(1 << 24); /* Clear bit 24 */ switch (pdev->device) { - case PCI_DEVICE_ID_JMICRON_JMB360: + case PCI_DEVICE_ID_JMICRON_JMB360: /* SATA single port */ + case PCI_DEVICE_ID_JMICRON_JMB362: /* SATA dual ports */ /* The controller should be in single function ahci mode */ conf1 |= 0x0002A100; /* Set 8, 13, 15, 17 */ break; @@ -1480,12 +1501,14 @@ static void quirk_jmicron_ata(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata); +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB362, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata); @@ -2081,6 +2104,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disabl DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi); /* Disable MSI on chipsets that are known to not support it */ static void __devinit quirk_disable_msi(struct pci_dev *dev) @@ -2092,6 +2116,8 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi); /* Go through the list of Hypertransport capabilities and * return 1 if a HT MSI capability is found and enabled */ @@ -2183,15 +2209,16 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 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 +/* The P5N32-SLI motherboards from Asus have 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. */ static void __devinit nvenet_msi_disable(struct pci_dev *dev) { - if (dmi_name_in_vendors("P5N32-SLI PREMIUM")) { + if (dmi_name_in_vendors("P5N32-SLI PREMIUM") || + dmi_name_in_vendors("P5N32-E SLI")) { dev_info(&dev->dev, - "Disabling msi for MCP55 NIC on P5N32-SLI Premium\n"); + "Disabling msi for MCP55 NIC on P5N32-SLI\n"); dev->no_msi = 1; } } @@ -2350,6 +2377,9 @@ static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all) int pos; int found; + if (!pci_msi_enabled()) + return; + /* check if there is HT MSI cap or enabled on this device */ found = ht_check_msi_mapping(dev); @@ -2513,6 +2543,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); #endif /* CONFIG_PCI_IOV */ diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index d919e96c0afd..7905285f707e 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -39,7 +39,7 @@ module_param(io_speed, int, 0444); #ifdef CONFIG_PCMCIA_PROBE #include /* mask of IRQs already reserved by other cards, we should avoid using them */ -static u8 pcmcia_used_irq[NR_IRQS]; +static u8 pcmcia_used_irq[32]; #endif @@ -719,6 +719,9 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) for (try = 0; try < 64; try++) { irq = try % 32; + if (irq > NR_IRQS) + continue; + /* marked as available by driver, and not blocked by userspace? */ if (!((mask >> irq) & 1)) continue; diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 55ca39dea42e..6e2a4ca4162e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -291,9 +291,15 @@ config THINKPAD_ACPI_VIDEO server running, phase of the moon, and the current mood of Schroedinger's cat. If you can use X.org's RandR to control your ThinkPad's video output ports instead of this feature, - don't think twice: do it and say N here to save some memory. + don't think twice: do it and say N here to save memory and avoid + bad interactions with X.org. - If you are not sure, say Y here. + NOTE: access to this feature is limited to processes with the + CAP_SYS_ADMIN capability, to avoid local DoS issues in platforms + where it interacts badly with X.org. + + If you are not sure, say Y here but do try to check if you could + be using X.org RandR instead. config THINKPAD_ACPI_HOTKEY_POLL bool "Support NVRAM polling for hot keys" diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 4226e5352738..c533b1c6556c 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -34,6 +34,7 @@ #include #include #include +#include #define EEEPC_LAPTOP_VERSION "0.1" @@ -135,6 +136,8 @@ struct eeepc_hotk { acpi_handle handle; /* the handle of the hotk device */ u32 cm_supported; /* the control methods supported by this BIOS */ + bool cpufv_disabled; + bool hotplug_disabled; uint init_flag; /* Init flags */ u16 event_count[128]; /* count for each event */ struct input_dev *inputdev; @@ -251,6 +254,14 @@ MODULE_AUTHOR("Corentin Chary, Eric Cooper"); MODULE_DESCRIPTION(EEEPC_HOTK_NAME); MODULE_LICENSE("GPL"); +static bool hotplug_disabled; + +module_param(hotplug_disabled, bool, 0644); +MODULE_PARM_DESC(hotplug_disabled, + "Disable hotplug for wireless device. " + "If your laptop need that, please report to " + "acpi4asus-user@lists.sourceforge.net."); + /* * ACPI Helpers */ @@ -467,6 +478,8 @@ static ssize_t store_cpufv(struct device *dev, struct eeepc_cpufv c; int rv, value; + if (ehotk->cpufv_disabled) + return -EPERM; if (get_cpufv(&c)) return -ENODEV; rv = parse_arg(buf, count, &value); @@ -478,6 +491,38 @@ static ssize_t store_cpufv(struct device *dev, return rv; } +static ssize_t show_cpufv_disabled(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", ehotk->cpufv_disabled); +} + +static ssize_t store_cpufv_disabled(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rv, value; + + rv = parse_arg(buf, count, &value); + if (rv < 0) + return rv; + + switch (value) { + case 0: + if (ehotk->cpufv_disabled) + pr_warning("cpufv enabled (not officially supported " + "on this model)\n"); + ehotk->cpufv_disabled = false; + return rv; + case 1: + return -EPERM; + default: + return -EINVAL; + } +} + + static struct device_attribute dev_attr_cpufv = { .attr = { .name = "cpufv", @@ -493,12 +538,22 @@ static struct device_attribute dev_attr_available_cpufv = { .show = show_available_cpufv }; +static struct device_attribute dev_attr_cpufv_disabled = { + .attr = { + .name = "cpufv_disabled", + .mode = 0644 }, + .show = show_cpufv_disabled, + .store = store_cpufv_disabled +}; + + static struct attribute *platform_attributes[] = { &dev_attr_camera.attr, &dev_attr_cardr.attr, &dev_attr_disp.attr, &dev_attr_cpufv.attr, &dev_attr_available_cpufv.attr, + &dev_attr_cpufv_disabled.attr, NULL }; @@ -564,6 +619,54 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } +static void eeepc_dmi_check(void) +{ + const char *model; + + model = dmi_get_system_info(DMI_PRODUCT_NAME); + if (!model) + return; + + /* + * Blacklist for setting cpufv (cpu speed). + * + * EeePC 4G ("701") implements CFVS, but it is not supported + * by the pre-installed OS, and the original option to change it + * in the BIOS setup screen was removed in later versions. + * + * Judging by the lack of "Super Hybrid Engine" on Asus product pages, + * this applies to all "701" models (4G/4G Surf/2G Surf). + * + * So Asus made a deliberate decision not to support it on this model. + * We have several reports that using it can cause the system to hang + * + * The hang has also been reported on a "702" (Model name "8G"?). + * + * We avoid dmi_check_system() / dmi_match(), because they use + * substring matching. We don't want to affect the "701SD" + * and "701SDX" models, because they do support S.H.E. + */ + if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) { + ehotk->cpufv_disabled = true; + pr_info("model %s does not officially support setting cpu " + "speed\n", model); + pr_info("cpufv disabled to avoid instability\n"); + } + + /* + * Blacklist for wlan hotplug + * + * Eeepc 1005HA doesn't work like others models and don't need the + * hotplug code. In fact, current hotplug code seems to unplug another + * device... + */ + if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 || + strcmp(model, "1005PE") == 0) { + ehotk->hotplug_disabled = true; + pr_info("wlan hotplug disabled\n"); + } +} + static void cmsg_quirk(int cm, const char *name) { int dummy; @@ -649,6 +752,8 @@ static void eeepc_rfkill_hotplug(void) struct pci_dev *dev; struct pci_bus *bus; bool blocked = eeepc_wlan_rfkill_blocked(); + bool absent; + u32 l; if (ehotk->wlan_rfkill) rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); @@ -662,6 +767,22 @@ static void eeepc_rfkill_hotplug(void) goto out_unlock; } + if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { + pr_err("Unable to read PCI config space?\n"); + goto out_unlock; + } + absent = (l == 0xffffffff); + + if (blocked != absent) { + pr_warning("BIOS says wireless lan is %s, " + "but the pci device is %s\n", + blocked ? "blocked" : "unblocked", + absent ? "absent" : "present"); + pr_warning("skipped wireless hotplug as probably " + "inappropriate for this model\n"); + goto out_unlock; + } + if (!blocked) { dev = pci_get_slot(bus, 0); if (dev) { @@ -1095,6 +1216,9 @@ static int eeepc_rfkill_init(struct device *dev) if (result && result != -ENODEV) goto exit; + if (ehotk->hotplug_disabled) + return 0; + result = eeepc_setup_pci_hotplug(); /* * If we get -EBUSY then something else is handling the PCI hotplug - @@ -1208,6 +1332,10 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device) device->driver_data = ehotk; ehotk->device = device; + ehotk->hotplug_disabled = hotplug_disabled; + + eeepc_dmi_check(); + result = eeepc_hotk_check(); if (result) goto fail_platform_driver; diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 1ee734c14cc1..7e51d5be8cc0 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -22,7 +22,7 @@ */ #define TPACPI_VERSION "0.23" -#define TPACPI_SYSFS_VERSION 0x020500 +#define TPACPI_SYSFS_VERSION 0x020600 /* * Changelog: @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -256,7 +257,7 @@ struct tp_acpi_drv_struct { struct ibm_struct { char *name; - int (*read) (char *); + int (*read) (struct seq_file *); int (*write) (char *); void (*exit) (void); void (*resume) (void); @@ -280,6 +281,7 @@ struct ibm_init_struct { char param[32]; int (*init) (struct ibm_init_struct *); + mode_t base_procfs_mode; struct ibm_struct *data; }; @@ -776,36 +778,25 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) **************************************************************************** ****************************************************************************/ -static int dispatch_procfs_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int dispatch_proc_show(struct seq_file *m, void *v) { - struct ibm_struct *ibm = data; - int len; + struct ibm_struct *ibm = m->private; if (!ibm || !ibm->read) return -EINVAL; - - len = ibm->read(page); - if (len < 0) - return len; - - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - - return len; + return ibm->read(m); } -static int dispatch_procfs_write(struct file *file, - const char __user *userbuf, - unsigned long count, void *data) +static int dispatch_proc_open(struct inode *inode, struct file *file) { - struct ibm_struct *ibm = data; + return single_open(file, dispatch_proc_show, PDE(inode)->data); +} + +static ssize_t dispatch_proc_write(struct file *file, + const char __user *userbuf, + size_t count, loff_t *pos) +{ + struct ibm_struct *ibm = PDE(file->f_path.dentry->d_inode)->data; char *kernbuf; int ret; @@ -834,6 +825,15 @@ static int dispatch_procfs_write(struct file *file, return ret; } +static const struct file_operations dispatch_proc_fops = { + .owner = THIS_MODULE, + .open = dispatch_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = dispatch_proc_write, +}; + static char *next_cmd(char **cmds) { char *start = *cmds; @@ -1264,6 +1264,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, struct tpacpi_rfk *atp_rfk; int res; bool sw_state = false; + bool hw_state; int sw_status; BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); @@ -1298,7 +1299,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, rfkill_init_sw_state(atp_rfk->rfkill, sw_state); } } - rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state()); + hw_state = tpacpi_rfk_check_hwblock_state(); + rfkill_set_hw_state(atp_rfk->rfkill, hw_state); res = rfkill_register(atp_rfk->rfkill); if (res < 0) { @@ -1311,6 +1313,9 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, } tpacpi_rfkill_switches[id] = atp_rfk; + + printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n", + name, (sw_state || hw_state) ? "" : "un"); return 0; } @@ -1383,12 +1388,11 @@ static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id, } /* procfs -------------------------------------------------------------- */ -static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p) +static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, + struct seq_file *m) { - int len = 0; - if (id >= TPACPI_RFK_SW_MAX) - len += sprintf(p + len, "status:\t\tnot supported\n"); + seq_printf(m, "status:\t\tnot supported\n"); else { int status; @@ -1402,13 +1406,13 @@ static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p) return status; } - len += sprintf(p + len, "status:\t\t%s\n", + seq_printf(m, "status:\t\t%s\n", (status == TPACPI_RFK_RADIO_ON) ? "enabled" : "disabled"); - len += sprintf(p + len, "commands:\tenable, disable\n"); + seq_printf(m, "commands:\tenable, disable\n"); } - return len; + return 0; } static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf) @@ -1779,7 +1783,7 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */ TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */ - TPV_QL0('7', 'E', 'D', '0'), /* R60e, R60i */ + TPV_QL1('7', 'E', 'D', '0', '1', '5'), /* R60e, R60i */ /* BIOS FW BIOS VERS EC FW EC VERS */ TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */ @@ -1795,8 +1799,8 @@ static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */ TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */ - TPV_QL0('7', 'B', 'D', '7'), /* X60/s */ - TPV_QL0('7', 'J', '3', '0'), /* X60t */ + TPV_QL1('7', 'B', 'D', '7', '4', '0'), /* X60/s */ + TPV_QL1('7', 'J', '3', '0', '1', '3'), /* X60t */ /* (0) - older versions lack DMI EC fw string and functionality */ /* (1) - older versions known to lack functionality */ @@ -1886,14 +1890,11 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) return 0; } -static int thinkpad_acpi_driver_read(char *p) +static int thinkpad_acpi_driver_read(struct seq_file *m) { - int len = 0; - - len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC); - len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION); - - return len; + seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC); + seq_printf(m, "version:\t%s\n", TPACPI_VERSION); + return 0; } static struct ibm_struct thinkpad_acpi_driver_data = { @@ -2073,6 +2074,7 @@ static struct attribute_set *hotkey_dev_attributes; static void tpacpi_driver_event(const unsigned int hkey_event); static void hotkey_driver_event(const unsigned int scancode); +static void hotkey_poll_setup(const bool may_warn); /* HKEY.MHKG() return bits */ #define TP_HOTKEY_TABLET_MASK (1 << 3) @@ -2189,7 +2191,8 @@ static int hotkey_mask_set(u32 mask) fwmask, hotkey_acpi_mask); } - hotkey_mask_warn_incomplete_mask(); + if (tpacpi_lifecycle != TPACPI_LIFE_EXITING) + hotkey_mask_warn_incomplete_mask(); return rc; } @@ -2254,6 +2257,8 @@ static int tpacpi_hotkey_driver_mask_set(const u32 mask) rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) & ~hotkey_source_mask); + hotkey_poll_setup(true); + mutex_unlock(&hotkey_mutex); return rc; @@ -2538,7 +2543,7 @@ static void hotkey_poll_stop_sync(void) } /* call with hotkey_mutex held */ -static void hotkey_poll_setup(bool may_warn) +static void hotkey_poll_setup(const bool may_warn) { const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask; const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask; @@ -2569,7 +2574,7 @@ static void hotkey_poll_setup(bool may_warn) } } -static void hotkey_poll_setup_safe(bool may_warn) +static void hotkey_poll_setup_safe(const bool may_warn) { mutex_lock(&hotkey_mutex); hotkey_poll_setup(may_warn); @@ -2587,7 +2592,11 @@ static void hotkey_poll_set_freq(unsigned int freq) #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ -static void hotkey_poll_setup_safe(bool __unused) +static void hotkey_poll_setup(const bool __unused) +{ +} + +static void hotkey_poll_setup_safe(const bool __unused) { } @@ -2597,16 +2606,11 @@ static int hotkey_inputdev_open(struct input_dev *dev) { switch (tpacpi_lifecycle) { case TPACPI_LIFE_INIT: - /* - * hotkey_init will call hotkey_poll_setup_safe - * at the appropriate moment - */ - return 0; - case TPACPI_LIFE_EXITING: - return -EBUSY; case TPACPI_LIFE_RUNNING: hotkey_poll_setup_safe(false); return 0; + case TPACPI_LIFE_EXITING: + return -EBUSY; } /* Should only happen if tpacpi_lifecycle is corrupt */ @@ -2617,7 +2621,7 @@ static int hotkey_inputdev_open(struct input_dev *dev) static void hotkey_inputdev_close(struct input_dev *dev) { /* disable hotkey polling when possible */ - if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING && + if (tpacpi_lifecycle != TPACPI_LIFE_EXITING && !(hotkey_source_mask & hotkey_driver_mask)) hotkey_poll_setup_safe(false); } @@ -3185,6 +3189,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) int res, i; int status; int hkeyv; + bool radiosw_state = false; + bool tabletsw_state = false; unsigned long quirks; @@ -3290,6 +3296,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_wlswemul) { tp_features.hotkey_wlsw = 1; + radiosw_state = !!tpacpi_wlsw_emulstate; printk(TPACPI_INFO "radio switch emulation enabled\n"); } else @@ -3297,6 +3304,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) /* Not all thinkpads have a hardware radio switch */ if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { tp_features.hotkey_wlsw = 1; + radiosw_state = !!status; printk(TPACPI_INFO "radio switch found; radios are %s\n", enabled(status, 0)); @@ -3308,11 +3316,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) /* For X41t, X60t, X61t Tablets... */ if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { tp_features.hotkey_tablet = 1; + tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK); printk(TPACPI_INFO "possible tablet mode switch found; " "ThinkPad in %s mode\n", - (status & TP_HOTKEY_TABLET_MASK)? - "tablet" : "laptop"); + (tabletsw_state) ? "tablet" : "laptop"); res = add_to_attr_set(hotkey_dev_attributes, &dev_attr_hotkey_tablet_mode.attr); } @@ -3347,16 +3355,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) TPACPI_HOTKEY_MAP_SIZE); } - set_bit(EV_KEY, tpacpi_inputdev->evbit); - set_bit(EV_MSC, tpacpi_inputdev->evbit); - set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); + input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; tpacpi_inputdev->keycode = hotkey_keycode_map; for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { if (hotkey_keycode_map[i] != KEY_RESERVED) { - set_bit(hotkey_keycode_map[i], - tpacpi_inputdev->keybit); + input_set_capability(tpacpi_inputdev, EV_KEY, + hotkey_keycode_map[i]); } else { if (i < sizeof(hotkey_reserved_mask)*8) hotkey_reserved_mask |= 1 << i; @@ -3364,12 +3370,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) } if (tp_features.hotkey_wlsw) { - set_bit(EV_SW, tpacpi_inputdev->evbit); - set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); + input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL); + input_report_switch(tpacpi_inputdev, + SW_RFKILL_ALL, radiosw_state); } if (tp_features.hotkey_tablet) { - set_bit(EV_SW, tpacpi_inputdev->evbit); - set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); + input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE); + input_report_switch(tpacpi_inputdev, + SW_TABLET_MODE, tabletsw_state); } /* Do not issue duplicate brightness change events to @@ -3436,8 +3444,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) tpacpi_inputdev->close = &hotkey_inputdev_close; hotkey_poll_setup_safe(true); - tpacpi_send_radiosw_update(); - tpacpi_input_send_tabletsw(); return 0; @@ -3545,49 +3551,57 @@ static bool hotkey_notify_usrevent(const u32 hkey, } } +static void thermal_dump_all_sensors(void); + static bool hotkey_notify_thermal(const u32 hkey, bool *send_acpi_ev, bool *ignore_acpi_ev) { + bool known = true; + /* 0x6000-0x6FFF: thermal alarms */ *send_acpi_ev = true; *ignore_acpi_ev = false; switch (hkey) { - case TP_HKEY_EV_ALARM_BAT_HOT: - printk(TPACPI_CRIT - "THERMAL ALARM: battery is too hot!\n"); - /* recommended action: warn user through gui */ - return true; - case TP_HKEY_EV_ALARM_BAT_XHOT: - printk(TPACPI_ALERT - "THERMAL EMERGENCY: battery is extremely hot!\n"); - /* recommended action: immediate sleep/hibernate */ - return true; - case TP_HKEY_EV_ALARM_SENSOR_HOT: - printk(TPACPI_CRIT - "THERMAL ALARM: " - "a sensor reports something is too hot!\n"); - /* recommended action: warn user through gui, that */ - /* some internal component is too hot */ - return true; - case TP_HKEY_EV_ALARM_SENSOR_XHOT: - printk(TPACPI_ALERT - "THERMAL EMERGENCY: " - "a sensor reports something is extremely hot!\n"); - /* recommended action: immediate sleep/hibernate */ - return true; case TP_HKEY_EV_THM_TABLE_CHANGED: printk(TPACPI_INFO "EC reports that Thermal Table has changed\n"); /* recommended action: do nothing, we don't have * Lenovo ATM information */ return true; + case TP_HKEY_EV_ALARM_BAT_HOT: + printk(TPACPI_CRIT + "THERMAL ALARM: battery is too hot!\n"); + /* recommended action: warn user through gui */ + break; + case TP_HKEY_EV_ALARM_BAT_XHOT: + printk(TPACPI_ALERT + "THERMAL EMERGENCY: battery is extremely hot!\n"); + /* recommended action: immediate sleep/hibernate */ + break; + case TP_HKEY_EV_ALARM_SENSOR_HOT: + printk(TPACPI_CRIT + "THERMAL ALARM: " + "a sensor reports something is too hot!\n"); + /* recommended action: warn user through gui, that */ + /* some internal component is too hot */ + break; + case TP_HKEY_EV_ALARM_SENSOR_XHOT: + printk(TPACPI_ALERT + "THERMAL EMERGENCY: " + "a sensor reports something is extremely hot!\n"); + /* recommended action: immediate sleep/hibernate */ + break; default: printk(TPACPI_ALERT "THERMAL ALERT: unknown thermal alarm received\n"); - return false; + known = false; } + + thermal_dump_all_sensors(); + + return known; } static void hotkey_notify(struct ibm_struct *ibm, u32 event) @@ -3635,13 +3649,19 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) break; case 3: /* 0x3000-0x3FFF: bay-related wakeups */ - if (hkey == TP_HKEY_EV_BAYEJ_ACK) { + switch (hkey) { + case TP_HKEY_EV_BAYEJ_ACK: hotkey_autosleep_ack = 1; printk(TPACPI_INFO "bay ejected\n"); hotkey_wakeup_hotunplug_complete_notify_change(); known_ev = true; - } else { + break; + case TP_HKEY_EV_OPTDRV_EJ: + /* FIXME: kick libata if SATA link offline */ + known_ev = true; + break; + default: known_ev = false; } break; @@ -3730,14 +3750,13 @@ static void hotkey_resume(void) } /* procfs -------------------------------------------------------------- */ -static int hotkey_read(char *p) +static int hotkey_read(struct seq_file *m) { int res, status; - int len = 0; if (!tp_features.hotkey) { - len += sprintf(p + len, "status:\t\tnot supported\n"); - return len; + seq_printf(m, "status:\t\tnot supported\n"); + return 0; } if (mutex_lock_killable(&hotkey_mutex)) @@ -3749,17 +3768,16 @@ static int hotkey_read(char *p) if (res) return res; - len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); + seq_printf(m, "status:\t\t%s\n", enabled(status, 0)); if (hotkey_all_mask) { - len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask); - len += sprintf(p + len, - "commands:\tenable, disable, reset, \n"); + seq_printf(m, "mask:\t\t0x%08x\n", hotkey_user_mask); + seq_printf(m, "commands:\tenable, disable, reset, \n"); } else { - len += sprintf(p + len, "mask:\t\tnot supported\n"); - len += sprintf(p + len, "commands:\tenable, disable, reset\n"); + seq_printf(m, "mask:\t\tnot supported\n"); + seq_printf(m, "commands:\tenable, disable, reset\n"); } - return len; + return 0; } static void hotkey_enabledisable_warn(bool enable) @@ -3852,7 +3870,7 @@ enum { TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: - off / last state */ + 0 = disable, 1 = enable */ }; enum { @@ -3898,10 +3916,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state) } #endif - /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ - status = TP_ACPI_BLUETOOTH_RESUMECTRL; if (state == TPACPI_RFK_RADIO_ON) - status |= TP_ACPI_BLUETOOTH_RADIOSSW; + status = TP_ACPI_BLUETOOTH_RADIOSSW + | TP_ACPI_BLUETOOTH_RESUMECTRL; + else + status = 0; if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) return -EIO; @@ -4025,9 +4044,9 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) } /* procfs -------------------------------------------------------------- */ -static int bluetooth_read(char *p) +static int bluetooth_read(struct seq_file *m) { - return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p); + return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, m); } static int bluetooth_write(char *buf) @@ -4052,7 +4071,7 @@ enum { TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: - off / last state */ + 0 = disable, 1 = enable */ }; #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" @@ -4089,10 +4108,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state) } #endif - /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */ - status = TP_ACPI_WANCARD_RESUMECTRL; if (state == TPACPI_RFK_RADIO_ON) - status |= TP_ACPI_WANCARD_RADIOSSW; + status = TP_ACPI_WANCARD_RADIOSSW + | TP_ACPI_WANCARD_RESUMECTRL; + else + status = 0; if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) return -EIO; @@ -4215,9 +4235,9 @@ static int __init wan_init(struct ibm_init_struct *iibm) } /* procfs -------------------------------------------------------------- */ -static int wan_read(char *p) +static int wan_read(struct seq_file *m) { - return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p); + return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, m); } static int wan_write(char *buf) @@ -4592,16 +4612,19 @@ static int video_expand_toggle(void) /* not reached */ } -static int video_read(char *p) +static int video_read(struct seq_file *m) { int status, autosw; - int len = 0; if (video_supported == TPACPI_VIDEO_NONE) { - len += sprintf(p + len, "status:\t\tnot supported\n"); - return len; + seq_printf(m, "status:\t\tnot supported\n"); + return 0; } + /* Even reads can crash X.org, so... */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + status = video_outputsw_get(); if (status < 0) return status; @@ -4610,20 +4633,20 @@ static int video_read(char *p) if (autosw < 0) return autosw; - len += sprintf(p + len, "status:\t\tsupported\n"); - len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); - len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); + seq_printf(m, "status:\t\tsupported\n"); + seq_printf(m, "lcd:\t\t%s\n", enabled(status, 0)); + seq_printf(m, "crt:\t\t%s\n", enabled(status, 1)); if (video_supported == TPACPI_VIDEO_NEW) - len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); - len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); - len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); - len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); + seq_printf(m, "dvi:\t\t%s\n", enabled(status, 3)); + seq_printf(m, "auto:\t\t%s\n", enabled(autosw, 0)); + seq_printf(m, "commands:\tlcd_enable, lcd_disable\n"); + seq_printf(m, "commands:\tcrt_enable, crt_disable\n"); if (video_supported == TPACPI_VIDEO_NEW) - len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); - len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); - len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); + seq_printf(m, "commands:\tdvi_enable, dvi_disable\n"); + seq_printf(m, "commands:\tauto_enable, auto_disable\n"); + seq_printf(m, "commands:\tvideo_switch, expand_toggle\n"); - return len; + return 0; } static int video_write(char *buf) @@ -4635,6 +4658,10 @@ static int video_write(char *buf) if (video_supported == TPACPI_VIDEO_NONE) return -ENODEV; + /* Even reads can crash X.org, let alone writes... */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + enable = 0; disable = 0; @@ -4815,25 +4842,24 @@ static void light_exit(void) flush_workqueue(tpacpi_wq); } -static int light_read(char *p) +static int light_read(struct seq_file *m) { - int len = 0; int status; if (!tp_features.light) { - len += sprintf(p + len, "status:\t\tnot supported\n"); + seq_printf(m, "status:\t\tnot supported\n"); } else if (!tp_features.light_status) { - len += sprintf(p + len, "status:\t\tunknown\n"); - len += sprintf(p + len, "commands:\ton, off\n"); + seq_printf(m, "status:\t\tunknown\n"); + seq_printf(m, "commands:\ton, off\n"); } else { status = light_get_status(); if (status < 0) return status; - len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); - len += sprintf(p + len, "commands:\ton, off\n"); + seq_printf(m, "status:\t\t%s\n", onoff(status, 0)); + seq_printf(m, "commands:\ton, off\n"); } - return len; + return 0; } static int light_write(char *buf) @@ -4911,20 +4937,18 @@ static void cmos_exit(void) device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); } -static int cmos_read(char *p) +static int cmos_read(struct seq_file *m) { - int len = 0; - /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, R30, R31, T20-22, X20-21 */ if (!cmos_handle) - len += sprintf(p + len, "status:\t\tnot supported\n"); + seq_printf(m, "status:\t\tnot supported\n"); else { - len += sprintf(p + len, "status:\t\tsupported\n"); - len += sprintf(p + len, "commands:\t ( is 0-21)\n"); + seq_printf(m, "status:\t\tsupported\n"); + seq_printf(m, "commands:\t ( is 0-21)\n"); } - return len; + return 0; } static int cmos_write(char *buf) @@ -5299,15 +5323,13 @@ static int __init led_init(struct ibm_init_struct *iibm) ((s) == TPACPI_LED_OFF ? "off" : \ ((s) == TPACPI_LED_ON ? "on" : "blinking")) -static int led_read(char *p) +static int led_read(struct seq_file *m) { - int len = 0; - if (!led_supported) { - len += sprintf(p + len, "status:\t\tnot supported\n"); - return len; + seq_printf(m, "status:\t\tnot supported\n"); + return 0; } - len += sprintf(p + len, "status:\t\tsupported\n"); + seq_printf(m, "status:\t\tsupported\n"); if (led_supported == TPACPI_LED_570) { /* 570 */ @@ -5316,15 +5338,15 @@ static int led_read(char *p) status = led_get_status(i); if (status < 0) return -EIO; - len += sprintf(p + len, "%d:\t\t%s\n", + seq_printf(m, "%d:\t\t%s\n", i, str_led_status(status)); } } - len += sprintf(p + len, "commands:\t" + seq_printf(m, "commands:\t" " on, off, blink ( is 0-15)\n"); - return len; + return 0; } static int led_write(char *buf) @@ -5397,18 +5419,16 @@ static int __init beep_init(struct ibm_init_struct *iibm) return (beep_handle)? 0 : 1; } -static int beep_read(char *p) +static int beep_read(struct seq_file *m) { - int len = 0; - if (!beep_handle) - len += sprintf(p + len, "status:\t\tnot supported\n"); + seq_printf(m, "status:\t\tnot supported\n"); else { - len += sprintf(p + len, "status:\t\tsupported\n"); - len += sprintf(p + len, "commands:\t ( is 0-17)\n"); + seq_printf(m, "status:\t\tsupported\n"); + seq_printf(m, "commands:\t ( is 0-17)\n"); } - return len; + return 0; } static int beep_write(char *buf) @@ -5461,8 +5481,11 @@ enum { /* TPACPI_THERMAL_TPEC_* */ TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */ TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */ TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */ + + TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */ }; + #define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ struct ibm_thermal_sensors_struct { s32 temp[TPACPI_MAX_THERMAL_SENSORS]; @@ -5552,6 +5575,28 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) return n; } +static void thermal_dump_all_sensors(void) +{ + int n, i; + struct ibm_thermal_sensors_struct t; + + n = thermal_get_sensors(&t); + if (n <= 0) + return; + + printk(TPACPI_NOTICE + "temperatures (Celsius):"); + + for (i = 0; i < n; i++) { + if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA) + printk(KERN_CONT " %d", (int)(t.temp[i] / 1000)); + else + printk(KERN_CONT " N/A"); + } + + printk(KERN_CONT "\n"); +} + /* sysfs temp##_input -------------------------------------------------- */ static ssize_t thermal_temp_input_show(struct device *dev, @@ -5567,7 +5612,7 @@ static ssize_t thermal_temp_input_show(struct device *dev, res = thermal_get_sensor(idx, &value); if (res) return res; - if (value == TP_EC_THERMAL_TMP_NA * 1000) + if (value == TPACPI_THERMAL_SENSOR_NA) return -ENXIO; return snprintf(buf, PAGE_SIZE, "%d\n", value); @@ -5736,7 +5781,7 @@ static void thermal_exit(void) case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_UPDT: sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, - &thermal_temp_input16_group); + &thermal_temp_input8_group); break; case TPACPI_THERMAL_NONE: default: @@ -5744,9 +5789,8 @@ static void thermal_exit(void) } } -static int thermal_read(char *p) +static int thermal_read(struct seq_file *m) { - int len = 0; int n, i; struct ibm_thermal_sensors_struct t; @@ -5754,16 +5798,16 @@ static int thermal_read(char *p) if (unlikely(n < 0)) return n; - len += sprintf(p + len, "temperatures:\t"); + seq_printf(m, "temperatures:\t"); if (n > 0) { for (i = 0; i < (n - 1); i++) - len += sprintf(p + len, "%d ", t.temp[i] / 1000); - len += sprintf(p + len, "%d\n", t.temp[i] / 1000); + seq_printf(m, "%d ", t.temp[i] / 1000); + seq_printf(m, "%d\n", t.temp[i] / 1000); } else - len += sprintf(p + len, "not supported\n"); + seq_printf(m, "not supported\n"); - return len; + return 0; } static struct ibm_struct thermal_driver_data = { @@ -5778,39 +5822,38 @@ static struct ibm_struct thermal_driver_data = { static u8 ecdump_regs[256]; -static int ecdump_read(char *p) +static int ecdump_read(struct seq_file *m) { - int len = 0; int i, j; u8 v; - len += sprintf(p + len, "EC " + seq_printf(m, "EC " " +00 +01 +02 +03 +04 +05 +06 +07" " +08 +09 +0a +0b +0c +0d +0e +0f\n"); for (i = 0; i < 256; i += 16) { - len += sprintf(p + len, "EC 0x%02x:", i); + seq_printf(m, "EC 0x%02x:", i); for (j = 0; j < 16; j++) { if (!acpi_ec_read(i + j, &v)) break; if (v != ecdump_regs[i + j]) - len += sprintf(p + len, " *%02x", v); + seq_printf(m, " *%02x", v); else - len += sprintf(p + len, " %02x", v); + seq_printf(m, " %02x", v); ecdump_regs[i + j] = v; } - len += sprintf(p + len, "\n"); + seq_putc(m, '\n'); if (j != 16) break; } /* These are way too dangerous to advertise openly... */ #if 0 - len += sprintf(p + len, "commands:\t0x 0x" + seq_printf(m, "commands:\t0x 0x" " ( is 00-ff, is 00-ff)\n"); - len += sprintf(p + len, "commands:\t0x " + seq_printf(m, "commands:\t0x " " ( is 00-ff, is 0-255)\n"); #endif - return len; + return 0; } static int ecdump_write(char *buf) @@ -6073,6 +6116,12 @@ static int brightness_get(struct backlight_device *bd) return status & TP_EC_BACKLIGHT_LVLMSK; } +static void tpacpi_brightness_notify_change(void) +{ + backlight_force_update(ibm_backlight_device, + BACKLIGHT_UPDATE_HOTKEY); +} + static struct backlight_ops ibm_backlight_data = { .get_brightness = brightness_get, .update_status = brightness_update_status, @@ -6094,13 +6143,13 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ /* Models with ATI GPUs that can use ECNVRAM */ - TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), + TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), /* R50,51 T40-42 */ TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), - TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), + TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC), /* R52 */ TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), /* Models with Intel Extreme Graphics 2 */ - TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), + TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), /* X40 */ TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), @@ -6227,6 +6276,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm) ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; backlight_update_status(ibm_backlight_device); + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, + "brightness: registering brightness hotkeys " + "as change notification\n"); + tpacpi_hotkey_driver_mask_set(hotkey_driver_mask + | TP_ACPI_HKEY_BRGHTUP_MASK + | TP_ACPI_HKEY_BRGHTDWN_MASK);; return 0; } @@ -6251,23 +6306,22 @@ static void brightness_exit(void) tpacpi_brightness_checkpoint_nvram(); } -static int brightness_read(char *p) +static int brightness_read(struct seq_file *m) { - int len = 0; int level; level = brightness_get(NULL); if (level < 0) { - len += sprintf(p + len, "level:\t\tunreadable\n"); + seq_printf(m, "level:\t\tunreadable\n"); } else { - len += sprintf(p + len, "level:\t\t%d\n", level); - len += sprintf(p + len, "commands:\tup, down\n"); - len += sprintf(p + len, "commands:\tlevel " + seq_printf(m, "level:\t\t%d\n", level); + seq_printf(m, "commands:\tup, down\n"); + seq_printf(m, "commands:\tlevel " " ( is 0-%d)\n", (tp_features.bright_16levels) ? 15 : 7); } - return len; + return 0; } static int brightness_write(char *buf) @@ -6303,6 +6357,9 @@ static int brightness_write(char *buf) * Doing it this way makes the syscall restartable in case of EINTR */ rc = brightness_set(level); + if (!rc && ibm_backlight_device) + backlight_force_update(ibm_backlight_device, + BACKLIGHT_UPDATE_SYSFS); return (rc == -EINTR)? -ERESTARTSYS : rc; } @@ -6321,22 +6378,21 @@ static struct ibm_struct brightness_driver_data = { static int volume_offset = 0x30; -static int volume_read(char *p) +static int volume_read(struct seq_file *m) { - int len = 0; u8 level; if (!acpi_ec_read(volume_offset, &level)) { - len += sprintf(p + len, "level:\t\tunreadable\n"); + seq_printf(m, "level:\t\tunreadable\n"); } else { - len += sprintf(p + len, "level:\t\t%d\n", level & 0xf); - len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6)); - len += sprintf(p + len, "commands:\tup, down, mute\n"); - len += sprintf(p + len, "commands:\tlevel " + seq_printf(m, "level:\t\t%d\n", level & 0xf); + seq_printf(m, "mute:\t\t%s\n", onoff(level, 6)); + seq_printf(m, "commands:\tup, down, mute\n"); + seq_printf(m, "commands:\tlevel " " ( is 0-15)\n"); } - return len; + return 0; } static int volume_write(char *buf) @@ -7488,9 +7544,8 @@ static void fan_resume(void) } } -static int fan_read(char *p) +static int fan_read(struct seq_file *m) { - int len = 0; int rc; u8 status; unsigned int speed = 0; @@ -7502,7 +7557,7 @@ static int fan_read(char *p) if (rc < 0) return rc; - len += sprintf(p + len, "status:\t\t%s\n" + seq_printf(m, "status:\t\t%s\n" "level:\t\t%d\n", (status != 0) ? "enabled" : "disabled", status); break; @@ -7513,54 +7568,54 @@ static int fan_read(char *p) if (rc < 0) return rc; - len += sprintf(p + len, "status:\t\t%s\n", + seq_printf(m, "status:\t\t%s\n", (status != 0) ? "enabled" : "disabled"); rc = fan_get_speed(&speed); if (rc < 0) return rc; - len += sprintf(p + len, "speed:\t\t%d\n", speed); + seq_printf(m, "speed:\t\t%d\n", speed); if (status & TP_EC_FAN_FULLSPEED) /* Disengaged mode takes precedence */ - len += sprintf(p + len, "level:\t\tdisengaged\n"); + seq_printf(m, "level:\t\tdisengaged\n"); else if (status & TP_EC_FAN_AUTO) - len += sprintf(p + len, "level:\t\tauto\n"); + seq_printf(m, "level:\t\tauto\n"); else - len += sprintf(p + len, "level:\t\t%d\n", status); + seq_printf(m, "level:\t\t%d\n", status); break; case TPACPI_FAN_NONE: default: - len += sprintf(p + len, "status:\t\tnot supported\n"); + seq_printf(m, "status:\t\tnot supported\n"); } if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) { - len += sprintf(p + len, "commands:\tlevel "); + seq_printf(m, "commands:\tlevel "); switch (fan_control_access_mode) { case TPACPI_FAN_WR_ACPI_SFAN: - len += sprintf(p + len, " ( is 0-7)\n"); + seq_printf(m, " ( is 0-7)\n"); break; default: - len += sprintf(p + len, " ( is 0-7, " + seq_printf(m, " ( is 0-7, " "auto, disengaged, full-speed)\n"); break; } } if (fan_control_commands & TPACPI_FAN_CMD_ENABLE) - len += sprintf(p + len, "commands:\tenable, disable\n" + seq_printf(m, "commands:\tenable, disable\n" "commands:\twatchdog ( " "is 0 (off), 1-120 (seconds))\n"); if (fan_control_commands & TPACPI_FAN_CMD_SPEED) - len += sprintf(p + len, "commands:\tspeed " + seq_printf(m, "commands:\tspeed " " ( is 0-65535)\n"); - return len; + return 0; } static int fan_write_cmd_level(const char *cmd, int *rc) @@ -7702,6 +7757,13 @@ static struct ibm_struct fan_driver_data = { */ static void tpacpi_driver_event(const unsigned int hkey_event) { + if (ibm_backlight_device) { + switch (hkey_event) { + case TP_HKEY_EV_BRGHT_UP: + case TP_HKEY_EV_BRGHT_DOWN: + tpacpi_brightness_notify_change(); + } + } } @@ -7834,19 +7896,20 @@ static int __init ibm_init(struct ibm_init_struct *iibm) "%s installed\n", ibm->name); if (ibm->read) { - entry = create_proc_entry(ibm->name, - S_IFREG | S_IRUGO | S_IWUSR, - proc_dir); + mode_t mode = iibm->base_procfs_mode; + + if (!mode) + mode = S_IRUGO; + if (ibm->write) + mode |= S_IWUSR; + entry = proc_create_data(ibm->name, mode, proc_dir, + &dispatch_proc_fops, ibm); if (!entry) { printk(TPACPI_ERR "unable to create proc entry %s\n", ibm->name); ret = -ENODEV; goto err_out; } - entry->data = ibm; - entry->read_proc = &dispatch_procfs_read; - if (ibm->write) - entry->write_proc = &dispatch_procfs_write; ibm->flags.proc_created = 1; } @@ -8027,6 +8090,7 @@ static struct ibm_init_struct ibms_init[] __initdata = { #ifdef CONFIG_THINKPAD_ACPI_VIDEO { .init = video_init, + .base_procfs_mode = S_IRUSR, .data = &video_driver_data, }, #endif @@ -8093,32 +8157,32 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp) return -EINVAL; } -module_param(experimental, int, 0); +module_param(experimental, int, 0444); MODULE_PARM_DESC(experimental, "Enables experimental features when non-zero"); module_param_named(debug, dbg_level, uint, 0); MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); -module_param(force_load, bool, 0); +module_param(force_load, bool, 0444); MODULE_PARM_DESC(force_load, "Attempts to load the driver even on a " "mis-identified ThinkPad when true"); -module_param_named(fan_control, fan_control_allowed, bool, 0); +module_param_named(fan_control, fan_control_allowed, bool, 0444); MODULE_PARM_DESC(fan_control, "Enables setting fan parameters features when true"); -module_param_named(brightness_mode, brightness_mode, uint, 0); +module_param_named(brightness_mode, brightness_mode, uint, 0444); MODULE_PARM_DESC(brightness_mode, "Selects brightness control strategy: " "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM"); -module_param(brightness_enable, uint, 0); +module_param(brightness_enable, uint, 0444); MODULE_PARM_DESC(brightness_enable, "Enables backlight control when 1, disables when 0"); -module_param(hotkey_report_mode, uint, 0); +module_param(hotkey_report_mode, uint, 0444); MODULE_PARM_DESC(hotkey_report_mode, "used for backwards compatibility with userspace, " "see documentation"); @@ -8141,25 +8205,25 @@ TPACPI_PARAM(volume); TPACPI_PARAM(fan); #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES -module_param(dbg_wlswemul, uint, 0); +module_param(dbg_wlswemul, uint, 0444); MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation"); module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0); MODULE_PARM_DESC(wlsw_state, "Initial state of the emulated WLSW switch"); -module_param(dbg_bluetoothemul, uint, 0); +module_param(dbg_bluetoothemul, uint, 0444); MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation"); module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0); MODULE_PARM_DESC(bluetooth_state, "Initial state of the emulated bluetooth switch"); -module_param(dbg_wwanemul, uint, 0); +module_param(dbg_wwanemul, uint, 0444); MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation"); module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0); MODULE_PARM_DESC(wwan_state, "Initial state of the emulated WWAN switch"); -module_param(dbg_uwbemul, uint, 0); +module_param(dbg_uwbemul, uint, 0444); MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation"); module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0); MODULE_PARM_DESC(uwb_state, @@ -8352,6 +8416,7 @@ static int __init thinkpad_acpi_module_init(void) PCI_VENDOR_ID_IBM; tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; + tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev; } for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { ret = ibm_init(&ibms_init[i]); @@ -8362,6 +8427,9 @@ static int __init thinkpad_acpi_module_init(void) return ret; } } + + tpacpi_lifecycle = TPACPI_LIFE_RUNNING; + ret = input_register_device(tpacpi_inputdev); if (ret < 0) { printk(TPACPI_ERR "unable to register input device\n"); @@ -8371,7 +8439,6 @@ static int __init thinkpad_acpi_module_init(void) tp_features.input_device_registered = 1; } - tpacpi_lifecycle = TPACPI_LIFE_RUNNING; return 0; } diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c index 936bae560fa1..dc628cb2e762 100644 --- a/drivers/power/apm_power.c +++ b/drivers/power/apm_power.c @@ -233,6 +233,7 @@ static int calculate_capacity(enum apm_source source) empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; + break; case SOURCE_VOLTAGE: full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 8fefe5a73558..4b38eaa9f5f0 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c @@ -271,14 +271,14 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32; + val->intval = (s16)be16_to_cpu(ec_word) * 9760L / 32; break; case POWER_SUPPLY_PROP_CURRENT_AVG: ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2); if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120; + val->intval = (s16)be16_to_cpu(ec_word) * 15625L / 120; break; case POWER_SUPPLY_PROP_CAPACITY: ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1); @@ -299,7 +299,7 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; + val->intval = (s16)be16_to_cpu(ec_word) * 100 / 256; break; case POWER_SUPPLY_PROP_TEMP_AMBIENT: ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); @@ -313,7 +313,7 @@ static int olpc_bat_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15; + val->intval = (s16)be16_to_cpu(ec_word) * 6250 / 15; break; case POWER_SUPPLY_PROP_SERIAL_NUMBER: ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8); diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 2bc9ef37b46f..0b6893ab577e 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -235,6 +235,7 @@ static void __exit rtc_exit(void) { rtc_dev_exit(); class_destroy(rtc_class); + idr_destroy(&rtc_idr); } subsys_initcall(rtc_init); diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 473e5f25e3dd..66c2d6a6d360 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -723,6 +723,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) } } + cmos_rtc.dev = dev; + dev_set_drvdata(dev, &cmos_rtc); + cmos_rtc.rtc = rtc_device_register(driver_name, dev, &cmos_rtc_ops, THIS_MODULE); if (IS_ERR(cmos_rtc.rtc)) { @@ -730,8 +733,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) goto cleanup0; } - cmos_rtc.dev = dev; - dev_set_drvdata(dev, &cmos_rtc); rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); spin_lock_irq(&rtc_lock); diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 03ea530981d1..44c4399ee714 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -271,12 +271,13 @@ static int coh901331_resume(struct platform_device *pdev) { struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); - if (device_may_wakeup(&pdev->dev)) + if (device_may_wakeup(&pdev->dev)) { disable_irq_wake(rtap->irq); - else + } else { clk_enable(rtap->clk); writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK); clk_disable(rtap->clk); + } return 0; } #else diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index eb99ee4fa0f5..861d91d012e0 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -775,7 +775,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, read_rtc: /* read RTC registers */ - tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf); + tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, buf); if (tmp != 8) { pr_debug("read error %d\n", tmp); err = -EIO; @@ -860,7 +860,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) tmp += 12; i2c_smbus_write_byte_data(client, - DS1307_REG_HOUR, + ds1307->offset + DS1307_REG_HOUR, bin2bcd(tmp)); } diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index e0d7b9991505..43bfffe1ec2b 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -456,8 +456,6 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(s3c_rtc_base + S3C2410_RTCCON)); - s3c_rtc_setfreq(&pdev->dev, 1); - device_init_wakeup(&pdev->dev, 1); /* register RTC and exit */ @@ -474,6 +472,9 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) rtc->max_user_freq = 128; platform_set_drvdata(pdev, rtc); + + s3c_rtc_setfreq(&pdev->dev, 1); + return 0; err_nortc: diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 138124fcfcad..126f240715a4 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -618,6 +618,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs) old_regs = set_irq_regs(regs); s390_idle_check(); irq_enter(); + __get_cpu_var(s390_idle).nohz_delay = 1; if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) /* Serve timer interrupts first. */ clock_comparator_work(); diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 0391d759dfdb..a5b8e7b92701 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -655,9 +655,9 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) /* Does this really need to be GFP_DMA? */ p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); if(!p) { - kfree (usg); - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + dprintk((KERN_DEBUG "aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", usg->sg[i].count,i,usg->count)); + kfree(usg); rcode = -ENOMEM; goto cleanup; } diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 63b521d615f2..3e89f8e06cbc 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) tinfo->curr.transport_version = 2; tinfo->goal.transport_version = 2; tinfo->goal.ppr_options = 0; - /* - * Remove any SCBs in the waiting for selection - * queue that may also be for this target so - * that command ordering is preserved. - */ - ahd_freeze_devq(ahd, scb); - ahd_qinfifo_requeue_tail(ahd, scb); + if (scb != NULL) { + /* + * Remove any SCBs in the waiting + * for selection queue that may + * also be for this target so that + * command ordering is preserved. + */ + ahd_freeze_devq(ahd, scb); + ahd_qinfifo_requeue_tail(ahd, scb); + } printerror = 0; } } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) @@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) MSG_EXT_WDTR_BUS_8_BIT, AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); - /* - * Remove any SCBs in the waiting for selection - * queue that may also be for this target so that - * command ordering is preserved. - */ - ahd_freeze_devq(ahd, scb); - ahd_qinfifo_requeue_tail(ahd, scb); + if (scb != NULL) { + /* + * Remove any SCBs in the waiting for + * selection queue that may also be for + * this target so that command ordering + * is preserved. + */ + ahd_freeze_devq(ahd, scb); + ahd_qinfifo_requeue_tail(ahd, scb); + } printerror = 0; } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) && ppr_busfree == 0) { @@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE); - /* - * Remove any SCBs in the waiting for selection - * queue that may also be for this target so that - * command ordering is preserved. - */ - ahd_freeze_devq(ahd, scb); - ahd_qinfifo_requeue_tail(ahd, scb); + if (scb != NULL) { + /* + * Remove any SCBs in the waiting for + * selection queue that may also be for + * this target so that command ordering + * is preserved. + */ + ahd_freeze_devq(ahd, scb); + ahd_qinfifo_requeue_tail(ahd, scb); + } printerror = 0; } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 && ahd_sent_msg(ahd, AHDMSG_1B, @@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) * the message phases. We check it last in case we * had to send some other message that caused a busfree. */ - if (printerror != 0 + if (scb != NULL && printerror != 0 && (lastphase == P_MESGIN || lastphase == P_MESGOUT) && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 477542602284..9e71ac611146 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2516,7 +2516,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt) if (info->scsi.phase == PHASE_IDLE) fas216_kick(info); - mod_timer(&info->eh_timer, 30 * HZ); + mod_timer(&info->eh_timer, jiffies + 30 * HZ); spin_unlock_irqrestore(&info->host_lock, flags); /* diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 9e8fce0f0c1b..bb96d7496215 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -4174,6 +4174,14 @@ static int ioc_general(void __user *arg, char *cmnd) ha = gdth_find_ha(gen.ionode); if (!ha) return -EFAULT; + + if (gen.data_len > INT_MAX) + return -EINVAL; + if (gen.sense_len > INT_MAX) + return -EINVAL; + if (gen.data_len + gen.sense_len > INT_MAX) + return -EINVAL; + if (gen.data_len + gen.sense_len != 0) { if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, FALSE, &paddr))) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index bb2c696c006a..2d66fac56180 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1969,7 +1969,7 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device, DECLARE_COMPLETION_ONSTACK(comp); int wait; unsigned long flags; - signed long timeout = init_timeout * HZ; + signed long timeout = IBMVFC_ABORT_WAIT_TIMEOUT * HZ; ENTER; do { @@ -2720,6 +2720,7 @@ static struct ibmvfc_async_crq *ibmvfc_next_async_crq(struct ibmvfc_host *vhost) if (crq->valid & 0x80) { if (++async_crq->cur == async_crq->size) async_crq->cur = 0; + rmb(); } else crq = NULL; @@ -2742,6 +2743,7 @@ static struct ibmvfc_crq *ibmvfc_next_crq(struct ibmvfc_host *vhost) if (crq->valid & 0x80) { if (++queue->cur == queue->size) queue->cur = 0; + rmb(); } else crq = NULL; @@ -2790,12 +2792,14 @@ static void ibmvfc_tasklet(void *data) while ((async = ibmvfc_next_async_crq(vhost)) != NULL) { ibmvfc_handle_async(async, vhost); async->valid = 0; + wmb(); } /* Pull all the valid messages off the CRQ */ while ((crq = ibmvfc_next_crq(vhost)) != NULL) { ibmvfc_handle_crq(crq, vhost); crq->valid = 0; + wmb(); } vio_enable_interrupts(vdev); @@ -2803,10 +2807,12 @@ static void ibmvfc_tasklet(void *data) vio_disable_interrupts(vdev); ibmvfc_handle_async(async, vhost); async->valid = 0; + wmb(); } else if ((crq = ibmvfc_next_crq(vhost)) != NULL) { vio_disable_interrupts(vdev); ibmvfc_handle_crq(crq, vhost); crq->valid = 0; + wmb(); } else done = 1; } diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 007fa1c9ef14..ef8e9f878973 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -38,6 +38,7 @@ #define IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT \ (IBMVFC_ADISC_TIMEOUT + IBMVFC_ADISC_CANCEL_TIMEOUT) #define IBMVFC_INIT_TIMEOUT 120 +#define IBMVFC_ABORT_WAIT_TIMEOUT 40 #define IBMVFC_MAX_REQUESTS_DEFAULT 100 #define IBMVFC_DEBUG 0 diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index f1a4246f890c..aab4a39cf84d 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -384,12 +384,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) WARN_ON(hdrlength >= 256); hdr->hlength = hdrlength & 0xFF; + hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn); if (session->tt->init_task && session->tt->init_task(task)) return -EIO; task->state = ISCSI_TASK_RUNNING; - hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++; conn->scsicmd_pdus_cnt++; @@ -2823,14 +2823,15 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, session->state = ISCSI_STATE_TERMINATE; else if (conn->stop_stage != STOP_CONN_RECOVER) session->state = ISCSI_STATE_IN_RECOVERY; + + old_stop_stage = conn->stop_stage; + conn->stop_stage = flag; spin_unlock_bh(&session->lock); del_timer_sync(&conn->transport_timer); iscsi_suspend_tx(conn); spin_lock_bh(&session->lock); - old_stop_stage = conn->stop_stage; - conn->stop_stage = flag; conn->c_stage = ISCSI_CONN_STOPPED; spin_unlock_bh(&session->lock); diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index e15501170698..0ee989fbb0fc 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -346,6 +346,7 @@ static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in, static struct ata_port_operations sas_sata_ops = { .phy_reset = sas_ata_phy_reset, .post_internal_cmd = sas_ata_post_internal, + .qc_defer = ata_std_qc_defer, .qc_prep = ata_noop_qc_prep, .qc_issue = sas_ata_qc_issue, .qc_fill_rtf = sas_ata_qc_fill_rtf, @@ -394,11 +395,15 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev, void sas_ata_task_abort(struct sas_task *task) { struct ata_queued_cmd *qc = task->uldd_task; + struct request_queue *q = qc->scsicmd->device->request_queue; struct completion *waiting; + unsigned long flags; /* Bounce SCSI-initiated commands to the SCSI EH */ if (qc->scsicmd) { + spin_lock_irqsave(q->queue_lock, flags); blk_abort_request(qc->scsicmd->request); + spin_unlock_irqrestore(q->queue_lock, flags); scsi_schedule_eh(qc->scsicmd->device->host); return; } diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 1c558d3bce18..39fb9aa93fe5 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -1025,6 +1025,8 @@ int __sas_task_abort(struct sas_task *task) void sas_task_abort(struct sas_task *task) { struct scsi_cmnd *sc = task->uldd_task; + struct request_queue *q = sc->device->request_queue; + unsigned long flags; /* Escape for libsas internal commands */ if (!sc) { @@ -1039,7 +1041,9 @@ void sas_task_abort(struct sas_task *task) return; } + spin_lock_irqsave(q->queue_lock, flags); blk_abort_request(sc->request); + spin_unlock_irqrestore(q->queue_lock, flags); scsi_schedule_eh(sc->device->host); } diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 518712cc7253..202fa0f4b805 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -3282,6 +3282,7 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) compat_alloc_user_space(sizeof(struct megasas_iocpacket)); int i; int error = 0; + compat_uptr_t ptr; if (clear_user(ioc, sizeof(*ioc))) return -EFAULT; @@ -3294,9 +3295,22 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) return -EFAULT; - for (i = 0; i < MAX_IOCTL_SGE; i++) { - compat_uptr_t ptr; + /* + * The sense_ptr is used in megasas_mgmt_fw_ioctl only when + * sense_len is not null, so prepare the 64bit value under + * the same condition. + */ + if (ioc->sense_len) { + void __user **sense_ioc_ptr = + (void __user **)(ioc->frame.raw + ioc->sense_off); + compat_uptr_t *sense_cioc_ptr = + (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off); + if (get_user(ptr, sense_cioc_ptr) || + put_user(compat_ptr(ptr), sense_ioc_ptr)) + return -EFAULT; + } + for (i = 0; i < MAX_IOCTL_SGE; i++) { if (get_user(ptr, &cioc->sgl[i].iov_base) || put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || copy_in_user(&ioc->sgl[i].iov_len, diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 1743640070ca..f10bf70c58df 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -5721,6 +5721,8 @@ _scsih_remove(struct pci_dev *pdev) struct _sas_port *mpt2sas_port; struct _sas_device *sas_device; struct _sas_node *expander_sibling; + struct _raid_device *raid_device, *next; + struct MPT2SAS_TARGET *sas_target_priv_data; struct workqueue_struct *wq; unsigned long flags; @@ -5734,6 +5736,21 @@ _scsih_remove(struct pci_dev *pdev) if (wq) destroy_workqueue(wq); + /* release all the volumes */ + list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, + list) { + if (raid_device->starget) { + sas_target_priv_data = + raid_device->starget->hostdata; + sas_target_priv_data->deleted = 1; + scsi_remove_target(&raid_device->starget->dev); + } + printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid" + "(0x%016llx)\n", ioc->name, raid_device->handle, + (unsigned long long) raid_device->wwid); + _scsih_raid_device_remove(ioc, raid_device); + } + /* free ports attached to the sas_host */ retry_again: list_for_each_entry(mpt2sas_port, diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index c790d45876c4..cae6b2cf492f 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -657,6 +657,7 @@ static struct pci_device_id __devinitdata mvs_pci_table[] = { { PCI_VDEVICE(MARVELL, 0x9180), chip_9180 }, { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1300), chip_1300 }, { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1320), chip_1320 }, + { PCI_VDEVICE(ADAPTEC2, 0x0450), chip_6440 }, { } /* terminate list */ }; diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 8371d917a9a2..49ac4148493b 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -1640,8 +1640,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha) uint16_t mb[MAILBOX_REGISTER_COUNT], i; int err; + spin_unlock_irq(ha->host->host_lock); err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, &ha->pdev->dev); + spin_lock_irq(ha->host->host_lock); if (err) { printk(KERN_ERR "Failed to load image \"%s\" err %d\n", ql1280_board_tbl[ha->devnum].fwname, err); @@ -1699,8 +1701,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) return -ENOMEM; #endif + spin_unlock_irq(ha->host->host_lock); err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, &ha->pdev->dev); + spin_lock_irq(ha->host->host_lock); if (err) { printk(KERN_ERR "Failed to load image \"%s\" err %d\n", ql1280_board_tbl[ha->devnum].fwname, err); diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f3d1d1afa95b..65ef03ca5687 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -453,6 +453,5 @@ extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); -extern struct scsi_qla_host * qla25xx_get_host(struct rsp_que *); #endif /* _QLA_GBL_H */ diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index b20a7169aac2..f3e5e30dd5ff 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1347,16 +1347,22 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) sense_len = rsp_info_len = resid_len = fw_resid_len = 0; if (IS_FWI2_CAPABLE(ha)) { - sense_len = le32_to_cpu(sts24->sense_len); - rsp_info_len = le32_to_cpu(sts24->rsp_data_len); - resid_len = le32_to_cpu(sts24->rsp_residual_count); - fw_resid_len = le32_to_cpu(sts24->residual_len); + if (scsi_status & SS_SENSE_LEN_VALID) + sense_len = le32_to_cpu(sts24->sense_len); + if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) + rsp_info_len = le32_to_cpu(sts24->rsp_data_len); + if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) + resid_len = le32_to_cpu(sts24->rsp_residual_count); + if (comp_status == CS_DATA_UNDERRUN) + fw_resid_len = le32_to_cpu(sts24->residual_len); rsp_info = sts24->data; sense_data = sts24->data; host_to_fcp_swap(sts24->data, sizeof(sts24->data)); } else { - sense_len = le16_to_cpu(sts->req_sense_length); - rsp_info_len = le16_to_cpu(sts->rsp_info_len); + if (scsi_status & SS_SENSE_LEN_VALID) + sense_len = le16_to_cpu(sts->req_sense_length); + if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) + rsp_info_len = le16_to_cpu(sts->rsp_info_len); resid_len = le32_to_cpu(sts->residual_length); rsp_info = sts->rsp_info; sense_data = sts->req_sense_data; @@ -1443,38 +1449,62 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) break; case CS_DATA_UNDERRUN: - resid = resid_len; + DEBUG2(printk(KERN_INFO + "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x. " + "resid=0x%x fw_resid=0x%x cdb=0x%x os_underflow=0x%x\n", + vha->host_no, cp->device->id, cp->device->lun, comp_status, + scsi_status, resid_len, fw_resid_len, cp->cmnd[0], + cp->underflow)); + /* Use F/W calculated residual length. */ - if (IS_FWI2_CAPABLE(ha)) { - if (!(scsi_status & SS_RESIDUAL_UNDER)) { - lscsi_status = 0; - } else if (resid != fw_resid_len) { - scsi_status &= ~SS_RESIDUAL_UNDER; - lscsi_status = 0; - } - resid = fw_resid_len; - } - + resid = IS_FWI2_CAPABLE(ha) ? fw_resid_len : resid_len; + scsi_set_resid(cp, resid); if (scsi_status & SS_RESIDUAL_UNDER) { - scsi_set_resid(cp, resid); - } else { - DEBUG2(printk(KERN_INFO - "scsi(%ld:%d:%d) UNDERRUN status detected " - "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x " - "os_underflow=0x%x\n", vha->host_no, - cp->device->id, cp->device->lun, comp_status, - scsi_status, resid_len, resid, cp->cmnd[0], - cp->underflow)); + if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) { + DEBUG2(printk( + "scsi(%ld:%d:%d:%d) Dropped frame(s) " + "detected (%x of %x bytes)...residual " + "length mismatch...retrying command.\n", + vha->host_no, cp->device->channel, + cp->device->id, cp->device->lun, resid, + scsi_bufflen(cp))); + cp->result = DID_ERROR << 16 | lscsi_status; + break; + } + + if (!lscsi_status && + ((unsigned)(scsi_bufflen(cp) - resid) < + cp->underflow)) { + qla_printk(KERN_INFO, ha, + "scsi(%ld:%d:%d:%d): Mid-layer underflow " + "detected (%x of %x bytes)...returning " + "error status.\n", vha->host_no, + cp->device->channel, cp->device->id, + cp->device->lun, resid, scsi_bufflen(cp)); + + cp->result = DID_ERROR << 16; + break; + } + } else if (!lscsi_status) { + DEBUG2(printk( + "scsi(%ld:%d:%d:%d) Dropped frame(s) detected " + "(%x of %x bytes)...firmware reported underrun..." + "retrying command.\n", vha->host_no, + cp->device->channel, cp->device->id, + cp->device->lun, resid, scsi_bufflen(cp))); + + cp->result = DID_ERROR << 16; + break; } + cp->result = DID_OK << 16 | lscsi_status; + /* * Check to see if SCSI Status is non zero. If so report SCSI * Status. */ if (lscsi_status != 0) { - cp->result = DID_OK << 16 | lscsi_status; - if (lscsi_status == SAM_STAT_TASK_SET_FULL) { DEBUG2(printk(KERN_INFO "scsi(%ld): QUEUE FULL status detected " @@ -1501,42 +1531,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) break; qla2x00_handle_sense(sp, sense_data, sense_len, rsp); - } else { - /* - * If RISC reports underrun and target does not report - * it then we must have a lost frame, so tell upper - * layer to retry it by reporting an error. - */ - if (!(scsi_status & SS_RESIDUAL_UNDER)) { - DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped " - "frame(s) detected (%x of %x bytes)..." - "retrying command.\n", - vha->host_no, cp->device->channel, - cp->device->id, cp->device->lun, resid, - scsi_bufflen(cp))); - - scsi_set_resid(cp, resid); - cp->result = DID_ERROR << 16; - break; - } - - /* Handle mid-layer underflow */ - if ((unsigned)(scsi_bufflen(cp) - resid) < - cp->underflow) { - qla_printk(KERN_INFO, ha, - "scsi(%ld:%d:%d:%d): Mid-layer underflow " - "detected (%x of %x bytes)...returning " - "error status.\n", vha->host_no, - cp->device->channel, cp->device->id, - cp->device->lun, resid, - scsi_bufflen(cp)); - - cp->result = DID_ERROR << 16; - break; - } - - /* Everybody online, looking good... */ - cp->result = DID_OK << 16; } break; @@ -2018,7 +2012,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) spin_lock_irq(&ha->hardware_lock); - vha = qla25xx_get_host(rsp); + vha = pci_get_drvdata(ha->pdev); qla24xx_process_response_queue(vha, rsp); if (!ha->mqenable) { WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); @@ -2246,30 +2240,28 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) /* If possible, enable MSI-X. */ if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && - !IS_QLA8432(ha) && !IS_QLA8001(ha)) - goto skip_msix; + !IS_QLA8432(ha) && !IS_QLA8001(ha)) + goto skip_msi; + + if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && + (ha->pdev->subsystem_device == 0x7040 || + ha->pdev->subsystem_device == 0x7041 || + ha->pdev->subsystem_device == 0x1705)) { + DEBUG2(qla_printk(KERN_WARNING, ha, + "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X,0x%X).\n", + ha->pdev->subsystem_vendor, + ha->pdev->subsystem_device)); + goto skip_msi; + } if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX || !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) { DEBUG2(qla_printk(KERN_WARNING, ha, "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n", ha->pdev->revision, ha->fw_attributes)); - goto skip_msix; } - if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && - (ha->pdev->subsystem_device == 0x7040 || - ha->pdev->subsystem_device == 0x7041 || - ha->pdev->subsystem_device == 0x1705)) { - DEBUG2(qla_printk(KERN_WARNING, ha, - "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X, 0x%X).\n", - ha->pdev->subsystem_vendor, - ha->pdev->subsystem_device)); - - goto skip_msi; - } - ret = qla24xx_enable_msix(ha, rsp); if (!ret) { DEBUG2(qla_printk(KERN_INFO, ha, @@ -2357,30 +2349,3 @@ int qla25xx_request_irq(struct rsp_que *rsp) msix->rsp = rsp; return ret; } - -struct scsi_qla_host * -qla25xx_get_host(struct rsp_que *rsp) -{ - srb_t *sp; - struct qla_hw_data *ha = rsp->hw; - struct scsi_qla_host *vha = NULL; - struct sts_entry_24xx *pkt; - struct req_que *req; - uint16_t que; - uint32_t handle; - - pkt = (struct sts_entry_24xx *) rsp->ring_ptr; - que = MSW(pkt->handle); - handle = (uint32_t) LSW(pkt->handle); - req = ha->req_q_map[que]; - if (handle < MAX_OUTSTANDING_COMMANDS) { - sp = req->outstanding_cmds[handle]; - if (sp) - return sp->fcport->vha; - else - goto base_que; - } -base_que: - vha = pci_get_drvdata(ha->pdev); - return vha; -} diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index e07b3617f019..4a69cc8c05e9 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -638,11 +638,15 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, static void qla_do_work(struct work_struct *work) { + unsigned long flags; struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); struct scsi_qla_host *vha; + struct qla_hw_data *ha = rsp->hw; - vha = qla25xx_get_host(rsp); + spin_lock_irqsave(&rsp->hw->hardware_lock, flags); + vha = pci_get_drvdata(ha->pdev); qla24xx_process_response_queue(vha, rsp); + spin_unlock_irqrestore(&rsp->hw->hardware_lock, flags); } /* create response queue */ diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index c4103bef41b5..bc3e3636a3b8 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -914,7 +914,8 @@ static int resp_start_stop(struct scsi_cmnd * scp, static sector_t get_sdebug_capacity(void) { if (scsi_debug_virtual_gb > 0) - return 2048 * 1024 * (sector_t)scsi_debug_virtual_gb; + return (sector_t)scsi_debug_virtual_gb * + (1073741824 / scsi_debug_sector_size); else return sdebug_store_sectors; } diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1b0060b791e8..573921d00070 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -301,7 +301,20 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) if (scmd->device->allow_restart && (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) return FAILED; - return SUCCESS; + + if (blk_barrier_rq(scmd->request)) + /* + * barrier requests should always retry on UA + * otherwise block will get a spurious error + */ + return NEEDS_RETRY; + else + /* + * for normal (non barrier) commands, pass the + * UA upwards for a determination in the + * completion functions + */ + return SUCCESS; /* these three are not supported */ case COPY_ABORTED: diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index b98f763931c5..d9564fb04f62 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -308,6 +308,9 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, case SG_SCSI_RESET_DEVICE: val = SCSI_TRY_RESET_DEVICE; break; + case SG_SCSI_RESET_TARGET: + val = SCSI_TRY_RESET_TARGET; + break; case SG_SCSI_RESET_BUS: val = SCSI_TRY_RESET_BUS; break; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index bc9a88145a71..b87fc30fad6b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -773,8 +773,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) * we already took a copy of the original into rq->errors which * is what gets returned to the user */ - if (sense_valid && sshdr.sense_key == RECOVERED_ERROR) { - if (!(req->cmd_flags & REQ_QUIET)) + if (sense_valid && (sshdr.sense_key == RECOVERED_ERROR)) { + /* if ATA PASS-THROUGH INFORMATION AVAILABLE skip + * print since caller wants ATA registers. Only occurs on + * SCSI ATA PASS_THROUGH commands when CK_COND=1 + */ + if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d)) + ; + else if (!(req->cmd_flags & REQ_QUIET)) scsi_print_sense("", cmd); result = 0; /* BLOCK_PC may have set error */ @@ -2426,7 +2432,8 @@ scsi_internal_device_unblock(struct scsi_device *sdev) sdev->sdev_state = SDEV_RUNNING; else if (sdev->sdev_state == SDEV_CREATED_BLOCK) sdev->sdev_state = SDEV_CREATED; - else + else if (sdev->sdev_state != SDEV_CANCEL && + sdev->sdev_state != SDEV_OFFLINE) return -EINVAL; spin_lock_irqsave(q->queue_lock, flags); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 392d8db33905..ad136c2be501 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -954,10 +954,11 @@ static void __scsi_remove_target(struct scsi_target *starget) list_for_each_entry(sdev, &shost->__devices, siblings) { if (sdev->channel != starget->channel || sdev->id != starget->id || - sdev->sdev_state == SDEV_DEL) + scsi_device_get(sdev)) continue; spin_unlock_irqrestore(shost->host_lock, flags); scsi_remove_device(sdev); + scsi_device_put(sdev); spin_lock_irqsave(shost->host_lock, flags); goto restart; } diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index bf52decfdef4..db02e31bae39 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -1215,6 +1215,15 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr, { struct fc_vport *vport = transport_class_to_vport(dev); struct Scsi_Host *shost = vport_to_shost(vport); + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { + spin_unlock_irqrestore(shost->host_lock, flags); + return -EBUSY; + } + vport->flags |= FC_VPORT_DELETING; + spin_unlock_irqrestore(shost->host_lock, flags); fc_queue_work(shost, &vport->vport_delete_work); return count; @@ -1804,6 +1813,9 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr, list_for_each_entry(vport, &fc_host->vports, peers) { if ((vport->channel == 0) && (vport->port_name == wwpn) && (vport->node_name == wwnn)) { + if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) + break; + vport->flags |= FC_VPORT_DELETING; match = 1; break; } @@ -3328,18 +3340,6 @@ fc_vport_terminate(struct fc_vport *vport) unsigned long flags; int stat; - spin_lock_irqsave(shost->host_lock, flags); - if (vport->flags & FC_VPORT_CREATING) { - spin_unlock_irqrestore(shost->host_lock, flags); - return -EBUSY; - } - if (vport->flags & (FC_VPORT_DEL)) { - spin_unlock_irqrestore(shost->host_lock, flags); - return -EALREADY; - } - vport->flags |= FC_VPORT_DELETING; - spin_unlock_irqrestore(shost->host_lock, flags); - if (i->f->vport_delete) stat = i->f->vport_delete(vport); else @@ -3796,8 +3796,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost, return; while (!blk_queue_plugged(q)) { - if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED)) - break; + if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) && + !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)) + break; req = blk_fetch_request(q); if (!req) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9093c7261f33..81a9d25ecaba 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -971,6 +971,7 @@ static void sd_prepare_flush(struct request_queue *q, struct request *rq) { rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->timeout = SD_TIMEOUT; + rq->retries = SD_MAX_RETRIES; rq->cmd[0] = SYNCHRONIZE_CACHE; rq->cmd_len = 10; } @@ -2048,11 +2049,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie) index = sdkp->index; dev = &sdp->sdev_gendev; - if (index < SD_MAX_DISKS) { - gd->major = sd_major((index & 0xf0) >> 4); - gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); - gd->minors = SD_MINORS; - } + gd->major = sd_major((index & 0xf0) >> 4); + gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); + gd->minors = SD_MINORS; + gd->fops = &sd_fops; gd->private_data = &sdkp->driver; gd->queue = sdkp->device->request_queue; @@ -2141,6 +2141,12 @@ static int sd_probe(struct device *dev) if (error) goto out_put; + if (index >= SD_MAX_DISKS) { + error = -ENODEV; + sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n"); + goto out_free_index; + } + error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); if (error) goto out_free_index; diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 55b034b72708..3c8a0248ea45 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -591,8 +591,6 @@ static int ses_intf_add(struct device *cdev, ses_dev->page10_len = len; buf = NULL; } - kfree(hdr_buf); - scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); if (!scomp) goto err_free; @@ -604,6 +602,8 @@ static int ses_intf_add(struct device *cdev, goto err_free; } + kfree(hdr_buf); + edev->scratch = ses_dev; for (i = 0; i < components; i++) edev->component[i].scratch = scomp + i; diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index deac67e35ce9..48ead154bd02 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -348,6 +348,8 @@ static const struct pnp_device_id pnp_dev_table[] = { { "FUJ02E6", 0 }, /* Fujitsu Wacom 2FGT Tablet PC device */ { "FUJ02E7", 0 }, + /* Fujitsu Wacom 1FGT Tablet PC device */ + { "FUJ02E9", 0 }, /* * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in * disguise) diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 300cea768d74..7feb902c32cb 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct uart_port *port, int flags) } } +#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) +/* + * Write a string to the serial port + * Note that this is called with interrupts already disabled + */ +static void cpm_uart_early_write(struct uart_cpm_port *pinfo, + const char *string, u_int count) +{ + unsigned int i; + cbd_t __iomem *bdp, *bdbase; + unsigned char *cpm_outp_addr; + + /* Get the address of the host memory buffer. + */ + bdp = pinfo->tx_cur; + bdbase = pinfo->tx_bd_base; + + /* + * Now, do each character. This is not as bad as it looks + * since this is a holding FIFO and not a transmitting FIFO. + * We could add the complexity of filling the entire transmit + * buffer, but we would just wait longer between accesses...... + */ + for (i = 0; i < count; i++, string++) { + /* Wait for transmitter fifo to empty. + * Ready indicates output is ready, and xmt is doing + * that, not that it is ready for us to send. + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + /* Send the character out. + * If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr = *string; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + + /* if a LF, also do CR... */ + if (*string == 10) { + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr = 13; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + pinfo->tx_cur = bdp; +} +#endif + #ifdef CONFIG_CONSOLE_POLL /* Serial polling routines for writing and reading from the uart while * in an interrupt or debug context. @@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uart_port *port, static char ch[2]; ch[0] = (char)c; - cpm_uart_early_write(pinfo->port.line, ch, 1); + cpm_uart_early_write(pinfo, ch, 1); } #endif /* CONFIG_CONSOLE_POLL */ @@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struct console *co, const char *s, u_int count) { struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; - unsigned int i; - cbd_t __iomem *bdp, *bdbase; - unsigned char *cp; unsigned long flags; int nolock = oops_in_progress; @@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, spin_lock_irqsave(&pinfo->port.lock, flags); } - /* Get the address of the host memory buffer. - */ - bdp = pinfo->tx_cur; - bdbase = pinfo->tx_bd_base; - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, s++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - /* Send the character out. - * If the buffer address is in the CPM DPRAM, don't - * convert it. - */ - cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); - *cp = *s; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*s == 10) { - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); - *cp = 13; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - pinfo->tx_cur = bdp; + cpm_uart_early_write(pinfo, s, count); if (unlikely(nolock)) { local_irq_restore(flags); diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 18130f11238e..2b550182a879 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -119,7 +119,8 @@ #define MX2_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */ #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ #define UCR3_BPEN (1<<0) /* Preset registers enable */ -#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ +#define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ +#define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ #define UCR4_INVR (1<<9) /* Inverted infrared reception */ #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ @@ -590,6 +591,9 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) return 0; } +/* half the RX buffer size */ +#define CTSTL 16 + static int imx_startup(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; @@ -606,6 +610,10 @@ static int imx_startup(struct uart_port *port) if (USE_IRDA(sport)) temp |= UCR4_IRSC; + /* set the trigger level for CTS */ + temp &= ~(UCR4_CTSTL_MASK<< UCR4_CTSTL_SHF); + temp |= CTSTL<< UCR4_CTSTL_SHF; + writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); if (USE_IRDA(sport)) { @@ -1279,7 +1287,7 @@ static int serial_imx_probe(struct platform_device *pdev) sport->use_irda = 1; #endif - if (pdata->init) { + if (pdata && pdata->init) { ret = pdata->init(pdev); if (ret) goto clkput; @@ -1292,7 +1300,7 @@ static int serial_imx_probe(struct platform_device *pdev) return 0; deinit: - if (pdata->exit) + if (pdata && pdata->exit) pdata->exit(pdev); clkput: clk_put(sport->clk); @@ -1321,7 +1329,7 @@ static int serial_imx_remove(struct platform_device *pdev) clk_disable(sport->clk); - if (pdata->exit) + if (pdata && pdata->exit) pdata->exit(pdev); iounmap(sport->port.membase); diff --git a/drivers/spi/rk29_spim.c b/drivers/spi/rk29_spim.c index b2ffd2ca1605..1227e6e836ff 100755 --- a/drivers/spi/rk29_spim.c +++ b/drivers/spi/rk29_spim.c @@ -40,7 +40,7 @@ QUICK_TRANSFER //#define QUICK_TRANSFER -#if 1 +#if 0 #define DBG printk #else #define DBG(x...) @@ -274,6 +274,7 @@ static int null_writer(struct rk29xx_spi *dws) static int null_reader(struct rk29xx_spi *dws) { u8 n_bytes = dws->n_bytes; + DBG("func: %s, line: %d\n", __FUNCTION__, __LINE__); while ((!(rk29xx_readw(dws, SPIM_SR) & SR_RF_EMPT)) && (dws->rx < dws->rx_end)) { rk29xx_readw(dws, SPIM_RXDR); @@ -299,9 +300,11 @@ static int u8_writer(struct rk29xx_spi *dws) static int u8_reader(struct rk29xx_spi *dws) { + spi_dump_regs(dws); while (!(rk29xx_readw(dws, SPIM_SR) & SR_RF_EMPT) && (dws->rx < dws->rx_end)) { *(u8 *)(dws->rx) = rk29xx_readw(dws, SPIM_RXDR) & 0xFFU; + DBG("rx: 0x%02x\n", *(u8 *)(dws->rx)); ++dws->rx; } @@ -330,6 +333,7 @@ static int u16_reader(struct rk29xx_spi *dws) && (dws->rx < dws->rx_end)) { temp = rk29xx_readw(dws, SPIM_RXDR); *(u16 *)(dws->rx) = temp; + //DBG("rx: 0x%04x\n", *(u16 *)(dws->rx)); dws->rx += 2; } @@ -551,7 +555,9 @@ static irqreturn_t interrupt_transfer(struct rk29xx_spi *dws) dws->write(dws); wait_till_not_busy(dws); } - dws->read(dws); + if (dws->rx) { + dws->read(dws); + } /* Re-enable the IRQ if there is still data left to tx */ if (dws->tx_end > dws->tx) @@ -560,6 +566,24 @@ static irqreturn_t interrupt_transfer(struct rk29xx_spi *dws) transfer_complete(dws); } + if (irq_status & SPI_INT_RXFI) { + spi_mask_intr(dws, SPI_INT_RXFI); + + dws->read(dws); + + /* Re-enable the IRQ if there is still data left to rx */ + if (dws->rx_end > dws->rx) { + left = ((dws->rx_end - dws->rx) / dws->n_bytes) - 1; + left = (left > int_level) ? int_level : left; + + rk29xx_writew(dws, SPIM_RXFTLR, left); + spi_umask_intr(dws, SPI_INT_RXFI); + } + else { + transfer_complete(dws); + } + } + return IRQ_HANDLED; } @@ -609,11 +633,12 @@ static void pump_transfers(unsigned long data) u8 imask = 0; u8 cs_change = 0; u16 txint_level = 0; + u16 rxint_level = 0; u16 clk_div = 0; u32 speed = 0; u32 cr0 = 0; - DBG(KERN_INFO "pump_transfers"); + DBG(KERN_INFO "pump_transfers\n"); /* Get current state information */ message = dws->cur_msg; @@ -742,11 +767,20 @@ static void pump_transfers(unsigned long data) * we only need set the TXEI IRQ, as TX/RX always happen syncronizely */ if (!dws->dma_mapped && !chip->poll_mode) { - int templen = dws->len / dws->n_bytes; - txint_level = dws->fifo_len / 2; - txint_level = (templen > txint_level) ? txint_level : templen; - - imask |= SPI_INT_TXEI; + int templen ; + + if (chip->tmode == SPI_TMOD_RO) { + templen = dws->len / dws->n_bytes - 1; + rxint_level = dws->fifo_len / 2; + rxint_level = (templen > rxint_level) ? rxint_level : templen; + imask |= SPI_INT_RXFI; + } + else { + templen = dws->len / dws->n_bytes; + txint_level = dws->fifo_len / 2; + txint_level = (templen > txint_level) ? txint_level : templen; + imask |= SPI_INT_TXEI; + } dws->transfer_handler = interrupt_transfer; } @@ -763,15 +797,19 @@ static void pump_transfers(unsigned long data) spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); spi_chip_sel(dws, spi->chip_select); + + rk29xx_writew(dws, SPIM_CTRLR1, dws->len-1); + spi_enable_chip(dws, 1); + + if (txint_level) + rk29xx_writew(dws, SPIM_TXFTLR, txint_level); + if (rxint_level) + rk29xx_writew(dws, SPIM_RXFTLR, rxint_level); /* Set the interrupt mask, for poll mode just diable all int */ spi_mask_intr(dws, 0xff); if (imask) spi_umask_intr(dws, imask); - if (txint_level) - rk29xx_writew(dws, SPIM_TXFTLR, txint_level); - - rk29xx_writew(dws, SPIM_CTRLR1, dws->len-1); - spi_enable_chip(dws, 1); + if (cs_change) dws->prev_chip = chip; } @@ -1093,7 +1131,7 @@ static void pump_messages(struct work_struct *work) dws->prev_chip = NULL; //ÿ¸öpump messageÊ±Ç¿ÖÆ¸üÐÂcs dxj /* Mark as busy and launch transfers */ - if(dws->cur_msg->is_dma_mapped && dws->cur_transfer->len > DMA_MIN_BYTES) { + if(dws->cur_msg->is_dma_mapped /*&& dws->cur_transfer->len > DMA_MIN_BYTES*/) { dws->busy = 1; spin_unlock_irqrestore(&dws->lock, flags); dma_transfer(dws); @@ -1606,7 +1644,6 @@ static int rk29xx_spi_setup(struct spi_device *spi) | (chip->tmode << SPI_TMOD_OFFSET); spi_set_ctldata(spi, chip); - DBG("RK29XX_SPI_SETUP: CRO: 0x%x ???????????????????\n", chip->cr0); return 0; } diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index ef9c6a04ad8f..744d3f6e4709 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c @@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) }, + { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC, 0x4318) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 9681536163ca..bbf1cb21a7d3 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -233,6 +233,9 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) { if (!cc->dev) return; /* We don't have a ChipCommon */ + if (cc->dev->id.revision >= 11) + cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); + ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); ssb_pmu_init(cc); chipco_powercontrol_init(cc); ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 9e50896233aa..321d9ef17b96 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -167,7 +167,7 @@ int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on) } /* Get the word-offset for a SSB_SPROM_XXX define. */ -#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16)) +#define SPOFF(offset) (((offset) - SSB_SPROM_BASE1) / sizeof(u16)) /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ #define SPEX16(_outvar, _offset, _mask, _shift) \ out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) @@ -253,7 +253,7 @@ static int sprom_do_read(struct ssb_bus *bus, u16 *sprom) int i; for (i = 0; i < bus->sprom_size; i++) - sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2)); + sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2)); return 0; } @@ -284,7 +284,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) ssb_printk("75%%"); else if (i % 2) ssb_printk("."); - writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2)); + writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); mmiowb(); msleep(20); } @@ -620,6 +620,28 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, int err = -ENOMEM; u16 *buf; + if (!ssb_is_sprom_available(bus)) { + ssb_printk(KERN_ERR PFX "No SPROM available!\n"); + return -ENODEV; + } + if (bus->chipco.dev) { /* can be unavailible! */ + /* + * get SPROM offset: SSB_SPROM_BASE1 except for + * chipcommon rev >= 31 or chip ID is 0x4312 and + * chipcommon status & 3 == 2 + */ + if (bus->chipco.dev->id.revision >= 31) + bus->sprom_offset = SSB_SPROM_BASE31; + else if (bus->chip_id == 0x4312 && + (bus->chipco.status & 0x03) == 2) + bus->sprom_offset = SSB_SPROM_BASE31; + else + bus->sprom_offset = SSB_SPROM_BASE1; + } else { + bus->sprom_offset = SSB_SPROM_BASE1; + } + ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset); + buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) goto out; diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index eb708431cb96..5f7154d9d04e 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -179,3 +179,18 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void) { return fallback_sprom; } + +/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ +bool ssb_is_sprom_available(struct ssb_bus *bus) +{ + /* status register only exists on chipcomon rev >= 11 and we need check + for >= 31 only */ + /* this routine differs from specs as we do not access SPROM directly + on PCMCIA */ + if (bus->bustype == SSB_BUSTYPE_PCI && + bus->chipco.dev && /* can be unavailible! */ + bus->chipco.dev->id.revision >= 31) + return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; + + return true; +} diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 34ee095555ab..35fb8174dc1a 100755 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -81,8 +81,6 @@ source "drivers/staging/rtl8192su/Kconfig" source "drivers/staging/rtl8192e/Kconfig" -source "drivers/staging/mimio/Kconfig" - source "drivers/staging/frontier/Kconfig" source "drivers/staging/android/Kconfig" @@ -132,5 +130,6 @@ source "drivers/staging/rk2818/rk1000_control/Kconfig" source "drivers/staging/rk2818/rk2818_power/Kconfig" source "drivers/staging/rk29/vivante/Kconfig" +source "drivers/staging/rk29/ipp/Kconfig" endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 5b2a508c7fcc..a8951fb6bf76 100755 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/ obj-$(CONFIG_RTL8187SE) += rtl8187se/ obj-$(CONFIG_RTL8192SU) += rtl8192su/ obj-$(CONFIG_RTL8192E) += rtl8192e/ -obj-$(CONFIG_INPUT_MIMIO) += mimio/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_STAGING_DREAM) += dream/ @@ -49,3 +48,4 @@ obj-$(CONFIG_RK1000_CONTROL) += rk2818/rk1000_control/ obj-$(CONFIG_RK1000_TVOUT) += rk2818/rk1000_tv/ obj-$(CONFIG_RK2818_POWER) += rk2818/rk2818_power/ obj-$(CONFIG_VIVANTE) += rk29/vivante/ +obj-$(CONFIG_RK29_IPP) += rk29/ipp/ diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 43c57b7688ab..8a05725cb1d0 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -609,13 +609,13 @@ static ssize_t class_set_picture(struct device *device, #define ASUS_OLED_DEVICE_ATTR(_file) dev_attr_asus_oled_##_file -static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(asus_oled_enabled, S_IWUSR | S_IRUGO, get_enabled, set_enabled); -static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture); +static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture); -static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO, +static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO, class_get_enabled, class_set_enabled); -static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture); +static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture); static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index d63c889ce557..1d6834d271fe 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -16,6 +16,7 @@ config COMEDI_DEBUG config COMEDI_PCI_DRIVERS tristate "Comedi PCI drivers" depends on COMEDI && PCI + select COMEDI_8255 default N ---help--- Enable lots of comedi PCI drivers to be built @@ -23,6 +24,7 @@ config COMEDI_PCI_DRIVERS config COMEDI_PCMCIA_DRIVERS tristate "Comedi PCMCIA drivers" depends on COMEDI && PCMCIA && PCCARD + select COMEDI_8255 default N ---help--- Enable lots of comedi PCMCIA and PCCARD drivers to be built @@ -33,3 +35,6 @@ config COMEDI_USB_DRIVERS default N ---help--- Enable lots of comedi USB drivers to be built + +config COMEDI_8255 + tristate diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index df2854d543cc..33b1d5268376 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -8,8 +8,10 @@ obj-$(CONFIG_COMEDI) += comedi_test.o obj-$(CONFIG_COMEDI) += comedi_parport.o obj-$(CONFIG_COMEDI) += pcm_common.o +# Comedi 8255 module +obj-$(CONFIG_COMEDI_8255) += 8255.o + # Comedi PCI drivers -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += 8255.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += acl7225b.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_035.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1032.o diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 9aef87fc81dc..27829e77ca08 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -123,7 +123,7 @@ static const struct ni_board_struct ni_boards[] = { .adbits = 12, .ai_fifo_depth = 1024, .alwaysdither = 0, - .gainlkup = ai_gain_16, + .gainlkup = ai_gain_4, .ai_speed = 5000, .n_aochan = 2, .aobits = 12, diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index cca4e869f0ec..5c9c1bc3eb61 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1,4 +1,4 @@ -#define DRIVER_VERSION "v2.2" +#define DRIVER_VERSION "v2.4" #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" #define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com" /* @@ -80,6 +80,9 @@ sampling rate. If you sample two channels you get 4kHz and so on. * 2.0: PWM seems to be stable and is not interfering with the other functions * 2.1: changed PWM API * 2.2: added firmware kernel request to fix an udev problem + * 2.3: corrected a bug in bulk timeouts which were far too short + * 2.4: fixed a bug which causes the driver to hang when it ran out of data. + * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it. * */ @@ -101,8 +104,8 @@ sampling rate. If you sample two channels you get 4kHz and so on. #define BOARDNAME "usbdux" -/* timeout for the USB-transfer */ -#define EZTIMEOUT 30 +/* timeout for the USB-transfer in ms*/ +#define BULK_TIMEOUT 1000 /* constants for "firmware" upload and download */ #define USBDUXSUB_FIRMWARE 0xA0 @@ -531,6 +534,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) } } /* tell comedi that data is there */ + s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; comedi_event(this_usbduxsub->comedidev, s); } @@ -750,7 +754,7 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub) /* Length */ 1, /* Timeout */ - EZTIMEOUT); + BULK_TIMEOUT); if (errcode < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (start)\n"); @@ -780,7 +784,7 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub) /* Length */ 1, /* Timeout */ - EZTIMEOUT); + BULK_TIMEOUT); if (errcode < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (stop)\n"); @@ -810,7 +814,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub, /* length */ len, /* timeout */ - EZTIMEOUT); + BULK_TIMEOUT); dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode); if (errcode < 0) { dev_err(&usbduxsub->interface->dev, "comedi_: upload failed\n"); @@ -1110,7 +1114,7 @@ static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type) usb_sndbulkpipe(this_usbduxsub->usbdev, COMMAND_OUT_EP), this_usbduxsub->dux_commands, SIZEOFDUXBUFFER, - &nsent, 10); + &nsent, BULK_TIMEOUT); if (result < 0) dev_err(&this_usbduxsub->interface->dev, "comedi%d: " "could not transmit dux_command to the usb-device, " @@ -1130,7 +1134,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command) usb_rcvbulkpipe(this_usbduxsub->usbdev, COMMAND_IN_EP), this_usbduxsub->insnBuffer, SIZEINSNBUF, - &nrec, 1); + &nrec, BULK_TIMEOUT); if (result < 0) { dev_err(&this_usbduxsub->interface->dev, "comedi%d: " "insn: USB error %d while receiving DUX command" diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index ef8fcc8c67bd..f6e04f83cd23 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -202,7 +202,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev) t->value = temp; \ return count; \ } \ - static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value); + static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value); show_int(enable); show_int(offline); diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c index c2809f2a2ce0..b12237f90db2 100644 --- a/drivers/staging/hv/Hv.c +++ b/drivers/staging/hv/Hv.c @@ -306,9 +306,9 @@ void HvCleanup(void) DPRINT_ENTER(VMBUS); if (gHvContext.SignalEventBuffer) { + kfree(gHvContext.SignalEventBuffer); gHvContext.SignalEventBuffer = NULL; gHvContext.SignalEventParam = NULL; - kfree(gHvContext.SignalEventBuffer); } if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c index f69ae33a91e3..3a38103ecfbd 100644 --- a/drivers/staging/hv/RingBuffer.c +++ b/drivers/staging/hv/RingBuffer.c @@ -192,7 +192,7 @@ GetRingBufferSize(RING_BUFFER_INFO* RingInfo) static inline u64 GetRingBufferIndices(RING_BUFFER_INFO* RingInfo) { - return ((u64)RingInfo->RingBuffer->WriteIndex << 32) || RingInfo->RingBuffer->ReadIndex; + return (u64)RingInfo->RingBuffer->WriteIndex << 32; } diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c index 26d79975387c..f05f4e125c48 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/RndisFilter.c @@ -756,6 +756,7 @@ static int RndisFilterOpenDevice(struct rndis_device *Device) ret = RndisFilterSetPacketFilter(Device, NDIS_PACKET_TYPE_BROADCAST | + NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); if (ret == 0) Device->State = RNDIS_DEV_DATAINITIALIZED; diff --git a/drivers/staging/hv/StorVscApi.h b/drivers/staging/hv/StorVscApi.h index 69c14066c479..3d8ff086fc7f 100644 --- a/drivers/staging/hv/StorVscApi.h +++ b/drivers/staging/hv/StorVscApi.h @@ -28,10 +28,10 @@ #include "VmbusApi.h" /* Defines */ -#define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE) +#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) #define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) -#define STORVSC_MAX_IO_REQUESTS 64 +#define STORVSC_MAX_IO_REQUESTS 128 /* * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 0d7459e2d036..547261d2537c 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -392,6 +392,9 @@ static const struct net_device_ops device_ops = { .ndo_start_xmit = netvsc_start_xmit, .ndo_get_stats = netvsc_get_stats, .ndo_set_multicast_list = netvsc_set_multicast_list, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, }; static int netvsc_probe(struct device *device) @@ -413,8 +416,7 @@ static int netvsc_probe(struct device *device) if (!net_drv_obj->Base.OnDeviceAdd) return -1; - net = alloc_netdev(sizeof(struct net_device_context), "seth%d", - ether_setup); + net = alloc_etherdev(sizeof(struct net_device_context)); if (!net) return -1; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index d49dc21d4cb4..2a4b147b0b38 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -532,7 +532,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); - if (j == 0) + if (bounce_addr == 0) bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); while (srclen) { @@ -593,7 +593,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, destlen = orig_sgl[i].length; ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); - if (j == 0) + if (bounce_addr == 0) bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); while (destlen) { @@ -652,6 +652,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, unsigned int request_size = 0; int i; struct scatterlist *sgl; + unsigned int sg_count = 0; DPRINT_ENTER(STORVSC_DRV); @@ -736,6 +737,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, request->DataBuffer.Length = scsi_bufflen(scmnd); if (scsi_sg_count(scmnd)) { sgl = (struct scatterlist *)scsi_sglist(scmnd); + sg_count = scsi_sg_count(scmnd); /* check if we need to bounce the sgl */ if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) { @@ -770,11 +772,12 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, scsi_sg_count(scmnd)); sgl = cmd_request->bounce_sgl; + sg_count = cmd_request->bounce_sgl_count; } request->DataBuffer.Offset = sgl[0].offset; - for (i = 0; i < scsi_sg_count(scmnd); i++) { + for (i = 0; i < sg_count; i++) { DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d \n", i, sgl[i].length, sgl[i].offset); request->DataBuffer.PfnArray[i] = diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 894eecfc63ca..6acc49a55a57 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "osd.h" #include "logging.h" #include "vmbus.h" @@ -946,6 +948,19 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) } } +static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = { + { + .ident = "Hyper-V", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), + }, + }, + { }, +}; +MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table); + static int __init vmbus_init(void) { int ret = 0; @@ -957,6 +972,9 @@ static int __init vmbus_init(void) vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel)); /* Todo: it is used for loglevel, to be ported to new kernel. */ + if (!dmi_check_system(microsoft_hv_dmi_table)) + return -ENODEV; + ret = vmbus_bus_init(VmbusInitialize); DPRINT_EXIT(VMBUS_DRV); @@ -973,6 +991,18 @@ static void __exit vmbus_exit(void) return; } +/* + * We use a PCI table to determine if we should autoload this driver This is + * needed by distro tools to determine if the hyperv drivers should be + * installed and/or configured. We don't do anything else with the table, but + * it needs to be present. + */ +const static struct pci_device_id microsoft_hv_pci_table[] = { + { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); + MODULE_LICENSE("GPL"); module_param(vmbus_irq, int, S_IRUGO); module_param(vmbus_loglevel, int, S_IRUGO); diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig index 7852d4a960c5..bc1ffbed3c8a 100644 --- a/drivers/staging/line6/Kconfig +++ b/drivers/staging/line6/Kconfig @@ -2,6 +2,7 @@ config LINE6_USB tristate "Line6 USB support" depends on USB && SND select SND_RAWMIDI + select SND_PCM help This is a driver for the guitar amp, cab, and effects modeller PODxt Pro by Line6 (and similar devices), supporting the diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c index 23ad08e17f84..13cb4c06b3c2 100644 --- a/drivers/staging/line6/control.c +++ b/drivers/staging/line6/control.c @@ -259,108 +259,108 @@ VARIAX_PARAM_R(float, mix2); VARIAX_PARAM_R(float, mix1); VARIAX_PARAM_R(int, pickup_wiring); -static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak); -static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, pod_set_wah_position); -static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain); -static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position); -static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold); -static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan); -static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup); -static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, pod_set_amp_model); -static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive); -static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass); -static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid); -static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid); -static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble); -static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, pod_set_highmid); -static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol); -static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix); -static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup); -static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency); -static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, pod_set_presence); -static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass); -static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable); -static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold); -static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time); -static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable); -static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable); -static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time); -static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable); -static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1); -static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1); -static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value); -static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass); -static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2); -static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix); -static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3); -static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable); -static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type); -static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay); -static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone); -static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay); -static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post); -static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency); -static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass); -static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable); -static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut); -static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut); -static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum); -static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post); -static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post); -static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, pod_set_di_model); -static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, pod_set_di_delay); -static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable); -static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value); -static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2); -static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3); -static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4); -static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5); -static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix); -static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post); -static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model); -static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency); -static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass); -static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision); -static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision); -static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable); -static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap); -static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign); -static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency); -static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner); -static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection); -static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model); -static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model); -static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel); -static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency); -static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency); -static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value); -static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2); -static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3); -static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4); -static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5); -static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6); -static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select); -static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4); -static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5); -static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post); -static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, pod_set_delay_model); -static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model); -static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb); -static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb); -static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, pod_set_wah_model); -static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume); -static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off); -static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select); -static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage); -static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain); -static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass); -static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain); -static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass); -static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain); -static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass); -static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass); -static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain); -static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass); +static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak); +static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position, pod_set_wah_position); +static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain); +static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position); +static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold); +static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan); +static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup); +static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model, pod_set_amp_model); +static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive); +static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass); +static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid); +static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid); +static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble); +static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid, pod_set_highmid); +static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol); +static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix); +static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup); +static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency); +static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence, pod_set_presence); +static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass); +static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable); +static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold); +static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time); +static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable); +static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable); +static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time); +static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable); +static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1); +static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1); +static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value); +static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass); +static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2); +static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix); +static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3); +static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable); +static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type); +static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay); +static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone); +static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay); +static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post); +static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency); +static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass); +static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable); +static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut); +static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut); +static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum); +static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post); +static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post); +static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model, pod_set_di_model); +static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay, pod_set_di_delay); +static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable); +static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value); +static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2); +static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3); +static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4); +static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5); +static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix); +static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post); +static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model); +static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency); +static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass); +static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision); +static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision); +static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable); +static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap); +static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign); +static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency); +static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner); +static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection); +static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model); +static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model); +static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel); +static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency); +static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency); +static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value); +static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2); +static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3); +static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4); +static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5); +static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6); +static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select); +static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4); +static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5); +static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post); +static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model, pod_set_delay_model); +static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model); +static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb); +static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb); +static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model, pod_set_wah_model); +static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume); +static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off); +static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select); +static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage); +static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain); +static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass); +static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain); +static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass); +static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain); +static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass); +static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass); +static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain); +static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass); static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write); static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, line6_nop_write); static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type, line6_nop_write); diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 89a2b17e9caf..a3b877edbaef 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -349,8 +349,8 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev, return count; } -static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit); -static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive); +static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit); +static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive); /* MIDI device destructor */ static int snd_line6_midi_free(struct snd_device *device) diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 4c5b9d584000..875d75a74f4b 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -912,33 +912,33 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1); #undef GET_SYSTEM_PARAM /* POD special files: */ -static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel); +static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel, pod_set_channel); static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write); static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write); static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write); -static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump); -static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf); -static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish); +static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump); +static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf); +static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish); static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write); -static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess); -static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level); +static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess); +static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level); static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write); static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write); -static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup); -static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel); -static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup); -static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing); +static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read, pod_set_retrieve_amp_setup); +static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read, pod_set_retrieve_channel); +static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read, pod_set_retrieve_effects_setup); +static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing, pod_set_routing); static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write); -static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup); -static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel); -static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup); -static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq); -static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute); +static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read, pod_set_store_amp_setup); +static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read, pod_set_store_channel); +static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read, pod_set_store_effects_setup); +static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq); +static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute); static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write); static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write); #if CREATE_RAW_FILE -static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw); #endif /* diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index eaa1229002aa..714687633dc8 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -117,8 +117,8 @@ static ssize_t toneport_set_led_green(struct device *dev, return count; } -static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_red); -static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_green); +static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read, toneport_set_led_red); +static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read, toneport_set_led_green); static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2) diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index f9d96984733a..12af54da4636 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -366,17 +366,17 @@ static ssize_t variax_set_raw2(struct device *dev, #endif /* Variax workbench special files: */ -static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model); -static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume); -static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone); +static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model, variax_set_model); +static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume, variax_set_volume); +static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone); static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write); static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write); static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write); -static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active); +static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active, variax_set_active); #if CREATE_RAW_FILE -static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw); -static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2); +static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw); +static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2); #endif diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig deleted file mode 100644 index 505dcb275796..000000000000 --- a/drivers/staging/mimio/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config INPUT_MIMIO - tristate "Mimio Xi interactive whiteboard support" - depends on USB && INPUT - default N - help - Say Y here if you want to use a Mimio Xi interactive - whiteboard device. - - To compile this driver as a module, choose M here: the - module will be called mimio. diff --git a/drivers/staging/mimio/Makefile b/drivers/staging/mimio/Makefile deleted file mode 100644 index 77807ee0450e..000000000000 --- a/drivers/staging/mimio/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_INPUT_MIMIO) += mimio.o diff --git a/drivers/staging/mimio/mimio.c b/drivers/staging/mimio/mimio.c deleted file mode 100644 index 1ba8103f5003..000000000000 --- a/drivers/staging/mimio/mimio.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Hardware event => input event mapping: - * - * - * - input.h:#define BTN_TOOL_PEN 0x140 black - input.h:#define BTN_TOOL_RUBBER 0x141 blue - input.h:#define BTN_TOOL_BRUSH 0x142 green - input.h:#define BTN_TOOL_PENCIL 0x143 red - input.h:#define BTN_TOOL_AIRBRUSH 0x144 eraser - input.h:#define BTN_TOOL_FINGER 0x145 small eraser - input.h:#define BTN_TOOL_MOUSE 0x146 mimio interactive - input.h:#define BTN_TOOL_LENS 0x147 mimio interactive but1 - input.h:#define LOCALBTN_TOOL_EXTRA1 0x14a mimio interactive but2 == BTN_TOUCH - input.h:#define LOCALBTN_TOOL_EXTRA2 0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS - input.h:#define LOCALBTN_TOOL_EXTRA3 0x14c unused == BTN_STYLUS2 - input.h:#define BTN_TOOL_DOUBLETAP 0x14d unused - input.h:#define BTN_TOOL_TRIPLETAP 0x14e unused - * - * MIMIO_EV_PENDOWN(MIMIO_PEN_K) => EV_KEY BIT(BTN_TOOL_PEN) - * MIMIO_EV_PENDOWN(MIMIO_PEN_B) => EV_KEY BIT(BTN_TOOL_RUBBER) - * MIMIO_EV_PENDOWN(MIMIO_PEN_G) => EV_KEY BIT(BTN_TOOL_BRUSH) - * MIMIO_EV_PENDOWN(MIMIO_PEN_R) => EV_KEY BIT(BTN_TOOL_PENCIL) - * MIMIO_EV_PENDOWN(MIMIO_PEN_E) => EV_KEY BIT(BTN_TOOL_AIRBRUSH) - * MIMIO_EV_PENDOWN(MIMIO_PEN_ES) => EV_KEY BIT(BTN_TOOL_FINGER) - * MIMIO_EV_PENDOWN(MIMIO_PEN_I) => EV_KEY BIT(BTN_TOOL_MOUSE) - * MIMIO_EV_PENDOWN(MIMIO_PEN_IL) => EV_KEY BIT(BTN_TOOL_LENS) - * MIMIO_EV_PENDOWN(MIMIO_PEN_IR) => EV_KEY BIT(BTN_TOOL_DOUBLETAP) - * MIMIO_EV_PENDOWN(MIMIO_PEN_EX) => EV_KEY BIT(BTN_TOOL_TRIPLETAP) - * MIMIO_EV_PENDATA => EV_ABS BIT(ABS_X), BIT(ABS_Y) - * MIMIO_EV_MEMRESET => EV_KEY BIT(BTN_0) - * MIMIO_EV_ACC(ACC_NEWPAGE) => EV_KEY BIT(BTN_1) - * MIMIO_EV_ACC(ACC_TAGPAGE) => EV_KEY BIT(BTN_2) - * MIMIO_EV_ACC(ACC_PRINTPAGE) => EV_KEY BIT(BTN_3) - * MIMIO_EV_ACC(ACC_MAXIMIZE) => EV_KEY BIT(BTN_4) - * MIMIO_EV_ACC(ACC_FINDCTLPNL) => EV_KEY BIT(BTN_5) - * - * - * open issues: - * - cold-load of data captured when mimio in standalone mode not yet - * supported; need to snoop Win32 box to see datastream for this. - * - mimio mouse not yet supported; need to snoop Win32 box to see the - * datastream for this. - */ -#include -#include -#include -#include -#include -#include - -#define DRIVER_VERSION "v0.031" -#define DRIVER_AUTHOR "mwilder@cs.nmsu.edu" -#define DRIVER_DESC "USB mimio-xi driver" - -enum {UPVALUE, DOWNVALUE, MOVEVALUE}; - -#define MIMIO_XRANGE_MAX 9600 -#define MIMIO_YRANGE_MAX 4800 - -#define LOCALBTN_TOOL_EXTRA1 BTN_TOUCH -#define LOCALBTN_TOOL_EXTRA2 BTN_STYLUS -#define LOCALBTN_TOOL_EXTRA3 BTN_STYLUS2 - -#define MIMIO_VENDOR_ID 0x08d3 -#define MIMIO_PRODUCT_ID 0x0001 -#define MIMIO_MAXPAYLOAD (8) -#define MIMIO_MAXNAMELEN (64) -#define MIMIO_TXWAIT (1) -#define MIMIO_TXDONE (2) - -#define MIMIO_EV_PENDOWN (0x22) -#define MIMIO_EV_PENDATA (0x24) -#define MIMIO_EV_PENUP (0x51) -#define MIMIO_EV_MEMRESET (0x45) -#define MIMIO_EV_ACC (0xb2) - -#define MIMIO_PEN_K (1) /* black pen */ -#define MIMIO_PEN_B (2) /* blue pen */ -#define MIMIO_PEN_G (3) /* green pen */ -#define MIMIO_PEN_R (4) /* red pen */ -/* 5, 6, 7, 8 are extra pens */ -#define MIMIO_PEN_E (9) /* big eraser */ -#define MIMIO_PEN_ES (10) /* lil eraser */ -#define MIMIO_PENJUMP_START (10) -#define MIMIO_PENJUMP (6) -#define MIMIO_PEN_I (17) /* mimio interactive */ -#define MIMIO_PEN_IL (18) /* mimio interactive button 1 */ -#define MIMIO_PEN_IR (19) /* mimio interactive button 2 */ - -#define MIMIO_PEN_MAX (MIMIO_PEN_IR) - -#define ACC_DONE (0) -#define ACC_NEWPAGE (1) -#define ACC_TAGPAGE (2) -#define ACC_PRINTPAGE (4) -#define ACC_MAXIMIZE (8) -#define ACC_FINDCTLPNL (16) - -#define isvalidtxsize(n) ((n) > 0 && (n) <= MIMIO_MAXPAYLOAD) - - -struct pktbuf { - unsigned char instr; - unsigned char buf[16]; - unsigned char *p; - unsigned char *q; -}; - -struct usbintendpt { - dma_addr_t dma; - struct urb *urb; - unsigned char *buf; - struct usb_endpoint_descriptor *desc; -}; - -struct mimio { - struct input_dev *idev; - struct usb_device *udev; - struct usb_interface *uifc; - int open; - int present; - int greeted; - int txflags; - char phys[MIMIO_MAXNAMELEN]; - struct usbintendpt in; - struct usbintendpt out; - struct pktbuf pktbuf; - unsigned char minor; - wait_queue_head_t waitq; - spinlock_t txlock; - void (*rxhandler)(struct mimio *, unsigned char *, unsigned int); - int last_pen_down; -}; - -static void mimio_close(struct input_dev *); -static void mimio_dealloc(struct mimio *); -static void mimio_disconnect(struct usb_interface *); -static int mimio_greet(struct mimio *); -static void mimio_irq_in(struct urb *); -static void mimio_irq_out(struct urb *); -static int mimio_open(struct input_dev *); -static int mimio_probe(struct usb_interface *, const struct usb_device_id *); -static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int); -static int mimio_tx(struct mimio *, const char *, int); - -static char mimio_name[] = "VirtualInk mimio-Xi"; -static struct usb_device_id mimio_table [] = { - { USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) }, - { USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */ - { } -}; - -MODULE_DEVICE_TABLE(usb, mimio_table); - -static struct usb_driver mimio_driver = { - .name = "mimio", - .probe = mimio_probe, - .disconnect = mimio_disconnect, - .id_table = mimio_table, -}; - -static DECLARE_MUTEX(disconnect_sem); - -static void mimio_close(struct input_dev *idev) -{ - struct mimio *mimio; - - mimio = input_get_drvdata(idev); - if (!mimio) { - dev_err(&idev->dev, "null mimio attached to input device\n"); - return; - } - - if (mimio->open <= 0) - dev_err(&idev->dev, "mimio not open.\n"); - else - mimio->open--; - - if (mimio->present == 0 && mimio->open == 0) - mimio_dealloc(mimio); -} - -static void mimio_dealloc(struct mimio *mimio) -{ - if (mimio == NULL) - return; - - usb_kill_urb(mimio->in.urb); - - usb_kill_urb(mimio->out.urb); - - if (mimio->idev) { - input_unregister_device(mimio->idev); - if (mimio->idev->grab) - input_close_device(mimio->idev->grab); - else - dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL" - " -- didn't call input_close_device\n"); - } - - usb_free_urb(mimio->in.urb); - - usb_free_urb(mimio->out.urb); - - if (mimio->in.buf) { - usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf, - mimio->in.dma); - } - - if (mimio->out.buf) - usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf, - mimio->out.dma); - - if (mimio->idev) - input_free_device(mimio->idev); - - kfree(mimio); -} - -static void mimio_disconnect(struct usb_interface *ifc) -{ - struct mimio *mimio; - - down(&disconnect_sem); - - mimio = usb_get_intfdata(ifc); - usb_set_intfdata(ifc, NULL); - dev_dbg(&mimio->idev->dev, "disconnect\n"); - - if (mimio) { - mimio->present = 0; - - if (mimio->open <= 0) - mimio_dealloc(mimio); - } - - up(&disconnect_sem); -} - -static int mimio_greet(struct mimio *mimio) -{ - const struct grtpkt { - int nbytes; - unsigned delay; - char data[8]; - } grtpkts[] = { - { 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } }, - { 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } }, - { 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } }, - { 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - { 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } }, - { 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, - }; - int rslt; - const struct grtpkt *pkt; - - for (pkt = grtpkts; pkt->nbytes; pkt++) { - rslt = mimio_tx(mimio, pkt->data, pkt->nbytes); - if (rslt) - return rslt; - if (pkt->delay) - msleep(pkt->delay); - } - - return 0; -} - -static void mimio_irq_in(struct urb *urb) -{ - int rslt; - char *data; - const char *reason = "going down"; - struct mimio *mimio; - - mimio = urb->context; - - if (mimio == NULL) - /* paranoia */ - return; - - switch (urb->status) { - case 0: - /* success */ - break; - case -ETIMEDOUT: - reason = "timeout -- unplugged?"; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - dev_dbg(&mimio->idev->dev, "%s.\n", reason); - return; - default: - dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n", - urb->status); - goto exit; - } - data = mimio->in.buf; - - if (mimio->rxhandler) - mimio->rxhandler(mimio, data, urb->actual_length); -exit: - /* - * Keep listening to device on same urb. - */ - rslt = usb_submit_urb(urb, GFP_ATOMIC); - if (rslt) - dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", - rslt); -} - -static void mimio_irq_out(struct urb *urb) -{ - unsigned long flags; - struct mimio *mimio; - - mimio = urb->context; - - if (urb->status) - dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status); - - spin_lock_irqsave(&mimio->txlock, flags); - mimio->txflags |= MIMIO_TXDONE; - spin_unlock_irqrestore(&mimio->txlock, flags); - wmb(); - wake_up(&mimio->waitq); -} - -static int mimio_open(struct input_dev *idev) -{ - int rslt; - struct mimio *mimio; - - rslt = 0; - down(&disconnect_sem); - mimio = input_get_drvdata(idev); - dev_dbg(&idev->dev, "mimio_open\n"); - - if (mimio == NULL) { - dev_err(&idev->dev, "null mimio.\n"); - rslt = -ENODEV; - goto exit; - } - - if (mimio->open++) - goto exit; - - if (mimio->present && !mimio->greeted) { - struct urb *urb = mimio->in.urb; - mimio->in.urb->dev = mimio->udev; - rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL); - if (rslt) { - dev_err(&idev->dev, "usb_submit_urb failure " - "(res = %d: %s). Not greeting.\n", - rslt, - (!urb ? "urb is NULL" : - (urb->hcpriv ? "urb->hcpriv is non-NULL" : - (!urb->complete ? "urb is not complete" : - (urb->number_of_packets <= 0 ? "urb has no packets" : - (urb->interval <= 0 ? "urb interval too small" : - "urb interval too large or some other error")))))); - rslt = -EIO; - goto exit; - } - rslt = mimio_greet(mimio); - if (rslt == 0) { - dev_dbg(&idev->dev, "Mimio greeted OK.\n"); - mimio->greeted = 1; - } else { - dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n", - rslt); - } - } - -exit: - up(&disconnect_sem); - return rslt; -} - -static int mimio_probe(struct usb_interface *ifc, - const struct usb_device_id *id) -{ - char path[64]; - int pipe, maxp; - struct mimio *mimio; - struct usb_device *udev; - struct usb_host_interface *hostifc; - struct input_dev *input_dev; - int res = 0; - int i; - - udev = interface_to_usbdev(ifc); - - mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL); - if (!mimio) - return -ENOMEM; - - input_dev = input_allocate_device(); - if (!input_dev) { - mimio_dealloc(mimio); - return -ENOMEM; - } - - mimio->uifc = ifc; - mimio->udev = udev; - mimio->pktbuf.p = mimio->pktbuf.buf; - mimio->pktbuf.q = mimio->pktbuf.buf; - /* init_input_dev(mimio->idev); */ - mimio->idev = input_dev; - init_waitqueue_head(&mimio->waitq); - spin_lock_init(&mimio->txlock); - hostifc = ifc->cur_altsetting; - - if (hostifc->desc.bNumEndpoints != 2) { - dev_err(&udev->dev, "Unexpected endpoint count: %d.\n", - hostifc->desc.bNumEndpoints); - mimio_dealloc(mimio); - return -ENODEV; - } - - mimio->in.desc = &(hostifc->endpoint[0].desc); - mimio->out.desc = &(hostifc->endpoint[1].desc); - - mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, - &mimio->in.dma); - mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL, - &mimio->out.dma); - - if (mimio->in.buf == NULL || mimio->out.buf == NULL) { - dev_err(&udev->dev, "usb_buffer_alloc failure.\n"); - mimio_dealloc(mimio); - return -ENOMEM; - } - - mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL); - mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL); - - if (mimio->in.urb == NULL || mimio->out.urb == NULL) { - dev_err(&udev->dev, "usb_alloc_urb failure.\n"); - mimio_dealloc(mimio); - return -ENOMEM; - } - - /* - * Build the input urb. - */ - pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress); - maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if (maxp > MIMIO_MAXPAYLOAD) - maxp = MIMIO_MAXPAYLOAD; - usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp, - mimio_irq_in, mimio, mimio->in.desc->bInterval); - mimio->in.urb->transfer_dma = mimio->in.dma; - mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - /* - * Build the output urb. - */ - pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress); - maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if (maxp > MIMIO_MAXPAYLOAD) - maxp = MIMIO_MAXPAYLOAD; - usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp, - mimio_irq_out, mimio, mimio->out.desc->bInterval); - mimio->out.urb->transfer_dma = mimio->out.dma; - mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - /* - * Build input device info - */ - usb_make_path(udev, path, 64); - snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path); - input_set_drvdata(input_dev, mimio); - /* input_dev->dev = &ifc->dev; */ - input_dev->open = mimio_open; - input_dev->close = mimio_close; - input_dev->name = mimio_name; - input_dev->phys = mimio->phys; - input_dev->dev.parent = &ifc->dev; - - input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor); - input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct); - input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice); - - input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); - for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i) - set_bit(i, input_dev->keybit); - - input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_1) | - BIT_MASK(BTN_2) | - BIT_MASK(BTN_3) | - BIT_MASK(BTN_4) | - BIT_MASK(BTN_5); - /* input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */ - input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); - input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0); - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); - -#if 0 - input_dev->absmin[ABS_X] = 0; - input_dev->absmin[ABS_Y] = 0; - input_dev->absmax[ABS_X] = 9600; - input_dev->absmax[ABS_Y] = 4800; - input_dev->absfuzz[ABS_X] = 0; - input_dev->absfuzz[ABS_Y] = 0; - input_dev->absflat[ABS_X] = 0; - input_dev->absflat[ABS_Y] = 0; -#endif - -#if 0 - /* this will just reduce the precision */ - input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */ - input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */ -#endif - - /* - * Register the input device. - */ - res = input_register_device(mimio->idev); - if (res) { - dev_err(&udev->dev, "input_register_device failure (%d)\n", - res); - mimio_dealloc(mimio); - return -EIO; - } - dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n", - input_dev->name, input_dev->phys, res); - - usb_set_intfdata(ifc, mimio); - mimio->present = 1; - - /* - * Submit the input urb to the usb subsystem. - */ - mimio->in.urb->dev = mimio->udev; - res = usb_submit_urb(mimio->in.urb, GFP_KERNEL); - if (res) { - dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n", - res); - mimio_dealloc(mimio); - return -EIO; - } - - /* - * Attempt to greet the mimio after giving - * it some post-init settling time. - * - * note: sometimes this sleep interval isn't - * long enough to permit the device to re-init - * after a hot-swap; maybe need to bump it up. - * - * As it is, this probably breaks module unloading support! - */ - msleep(1024); - - res = mimio_greet(mimio); - if (res == 0) { - dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n"); - mimio->greeted = 1; - mimio->rxhandler = mimio_rx_handler; - } else { - dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res); - } - - return 0; -} - -static int handle_mimio_rx_penupdown(struct mimio *mimio, - int down, - const char *const instr[], - const int instr_ofst[]) -{ - int penid, x; - if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3)) - return 1; /* partial pkt */ - - if (down) { - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ - *(mimio->pktbuf.p + 2); - if (x != *(mimio->pktbuf.p + 3)) { - dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n", - down ? "DOWN":"UP"); - /* skip this event data */ - mimio->pktbuf.p += 4; - /* decode any remaining events */ - return 0; - } - penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2); - if (penid > MIMIO_PEN_MAX) { - dev_dbg(&mimio->idev->dev, - "Unmapped penID (not in [0, %d]): %d\n", - MIMIO_PEN_MAX, (int)mimio->pktbuf.instr); - penid = mimio->pktbuf.instr = 0; - } - mimio->last_pen_down = penid; - } else { - penid = mimio->last_pen_down; - } - dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid], - instr_ofst[penid], penid, down ? "down" : "up"); - - if (instr_ofst[penid] >= 0) { - int code = BTN_TOOL_PEN + instr_ofst[penid]; - int value = down ? DOWNVALUE : UPVALUE; - if (code > KEY_MAX) - dev_dbg(&mimio->idev->dev, "input_event will ignore " - "-- code (%d) > KEY_MAX\n", code); - if (!test_bit(code, mimio->idev->keybit)) - dev_dbg(&mimio->idev->dev, "input_event will ignore " - "-- bit for code (%d) not enabled\n", code); - if (!!test_bit(code, mimio->idev->key) == value) - dev_dbg(&mimio->idev->dev, "input_event will ignore " - "-- bit for code (%d) already set to %d\n", - code, value); - if (value != DOWNVALUE) { - /* input_regs(mimio->idev, regs); */ - input_report_key(mimio->idev, code, value); - input_sync(mimio->idev); - } else { - /* wait until we get some coordinates */ - } - } else { - dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 " - "- not sending\n", penid, instr_ofst[penid]); - } - mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */ - return 0; -} - -/* - * Stay tuned for partial-packet excitement. - * - * This routine buffers data packets received from the mimio device - * in the mimio's data space. This buffering is necessary because - * the mimio's in endpoint can serve us partial packets of data, and - * we want the driver to support the servicing of multiple mimios. - * Empirical evidence gathered so far suggests that the method of - * buffering packet data in the mimio's data space works. Previous - * versions of this driver did not buffer packet data in each mimio's - * data-space, and were therefore not able to service multiple mimios. - * Note that since the caller of this routine is running in interrupt - * context, care needs to be taken to ensure that this routine does not - * become bloated, and it may be that another spinlock is needed in each - * mimio to guard the buffered packet data properly. - */ -static void mimio_rx_handler(struct mimio *mimio, - unsigned char *data, - unsigned int nbytes) -{ - struct device *dev = &mimio->idev->dev; - unsigned int x; - unsigned int y; - static const char * const instr[] = { - "?0", - "black pen", "blue pen", "green pen", "red pen", - "brown pen", "orange pen", "purple pen", "yellow pen", - "big eraser", "lil eraser", - "?11", "?12", "?13", "?14", "?15", "?16", - "mimio interactive", "interactive button1", - "interactive button2" - }; - - /* Mimio Interactive gives: - * down: [0x22 0x01 0x11 0x32 0x24] - * b1 : [0x22 0x01 0x12 0x31 0x24] - * b2 : [0x22 0x01 0x13 0x30 0x24] - */ - static const int instr_ofst[] = { - -1, - 0, 1, 2, 3, - 9, 9, 9, 9, - 4, 5, - -1, -1, -1, -1, -1, -1, - 6, 7, 8, - }; - - memcpy(mimio->pktbuf.q, data, nbytes); - mimio->pktbuf.q += nbytes; - - while (mimio->pktbuf.p < mimio->pktbuf.q) { - int t = *mimio->pktbuf.p; - switch (t) { - case MIMIO_EV_PENUP: - case MIMIO_EV_PENDOWN: - if (handle_mimio_rx_penupdown(mimio, - t == MIMIO_EV_PENDOWN, - instr, instr_ofst)) - return; /* partial packet */ - break; - - case MIMIO_EV_PENDATA: - if (mimio->pktbuf.q - mimio->pktbuf.p < 6) - /* partial pkt */ - return; - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ - *(mimio->pktbuf.p + 2) ^ - *(mimio->pktbuf.p + 3) ^ - *(mimio->pktbuf.p + 4); - if (x != *(mimio->pktbuf.p + 5)) { - dev_dbg(dev, "EV_PENDATA: bad xsum.\n"); - mimio->pktbuf.p += 6; /* skip this event data */ - break; /* decode any remaining events */ - } - x = *(mimio->pktbuf.p + 1); - x <<= 8; - x |= *(mimio->pktbuf.p + 2); - y = *(mimio->pktbuf.p + 3); - y <<= 8; - y |= *(mimio->pktbuf.p + 4); - dev_dbg(dev, "coord: (%d, %d)\n", x, y); - if (instr_ofst[mimio->pktbuf.instr] >= 0) { - int code = BTN_TOOL_PEN + - instr_ofst[mimio->last_pen_down]; -#if 0 - /* Utter hack to ensure we get forwarded _AND_ - * so we can identify when a complete signal is - * received */ - mimio->idev->abs[ABS_Y] = -1; - mimio->idev->abs[ABS_X] = -1; -#endif - /* input_regs(mimio->idev, regs); */ - input_report_abs(mimio->idev, ABS_X, x); - input_report_abs(mimio->idev, ABS_Y, y); - /* fake a penup */ - change_bit(code, mimio->idev->key); - input_report_key(mimio->idev, - code, - DOWNVALUE); - /* always sync here */ - mimio->idev->sync = 0; - input_sync(mimio->idev); - } - mimio->pktbuf.p += 6; - break; - case MIMIO_EV_MEMRESET: - if (mimio->pktbuf.q - mimio->pktbuf.p < 7) - /* partial pkt */ - return; - dev_dbg(dev, "mem-reset.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_0, 1); - input_event(mimio->idev, EV_KEY, BTN_0, 0); - input_sync(mimio->idev); - mimio->pktbuf.p += 7; - break; - case MIMIO_EV_ACC: - if (mimio->pktbuf.q - mimio->pktbuf.p < 4) - /* partial pkt */ - return; - x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^ - *(mimio->pktbuf.p + 2); - if (x != *(mimio->pktbuf.p + 3)) { - dev_dbg(dev, "EV_ACC: bad xsum.\n"); - mimio->pktbuf.p += 4; /* skip this event data */ - break; /* decode any remaining events */ - } - switch (*(mimio->pktbuf.p + 2)) { - case ACC_NEWPAGE: - dev_dbg(&mimio->idev->dev, "new-page.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_1, 1); - input_event(mimio->idev, EV_KEY, BTN_1, 0); - input_sync(mimio->idev); - break; - case ACC_TAGPAGE: - dev_dbg(&mimio->idev->dev, "tag-page.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_2, 1); - input_event(mimio->idev, EV_KEY, BTN_2, 0); - input_sync(mimio->idev); - break; - case ACC_PRINTPAGE: - dev_dbg(&mimio->idev->dev, "print-page.\n"); - /* input_regs(mimio->idev, regs);*/ - input_event(mimio->idev, EV_KEY, BTN_3, 1); - input_event(mimio->idev, EV_KEY, BTN_3, 0); - input_sync(mimio->idev); - break; - case ACC_MAXIMIZE: - dev_dbg(&mimio->idev->dev, - "maximize-window.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_4, 1); - input_event(mimio->idev, EV_KEY, BTN_4, 0); - input_sync(mimio->idev); - break; - case ACC_FINDCTLPNL: - dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n"); - /* input_regs(mimio->idev, regs); */ - input_event(mimio->idev, EV_KEY, BTN_5, 1); - input_event(mimio->idev, EV_KEY, BTN_5, 0); - input_sync(mimio->idev); - break; - case ACC_DONE: - dev_dbg(&mimio->idev->dev, "acc-done.\n"); - /* no event is dispatched to the input - * subsystem for this device event. - */ - break; - default: - dev_dbg(dev, "unknown acc event.\n"); - break; - } - mimio->pktbuf.p += 4; - break; - default: - mimio->pktbuf.p++; - break; - } - } - - /* - * No partial event was received, so reset mimio's pktbuf ptrs. - */ - mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf; -} - -static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes) -{ - int rslt; - int timeout; - unsigned long flags; - DECLARE_WAITQUEUE(wait, current); - - if (!(isvalidtxsize(nbytes))) { - dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n", - nbytes); - return -EINVAL; - } - - /* - * Init the out urb and copy the data to send. - */ - mimio->out.urb->dev = mimio->udev; - mimio->out.urb->transfer_buffer_length = nbytes; - memcpy(mimio->out.urb->transfer_buffer, buf, nbytes); - - /* - * Send the data. - */ - spin_lock_irqsave(&mimio->txlock, flags); - mimio->txflags = MIMIO_TXWAIT; - rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC); - spin_unlock_irqrestore(&mimio->txlock, flags); - dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt); - - if (rslt) { - dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n", - rslt); - return rslt; - } - - /* - * Wait for completion to be signalled (the mimio_irq_out - * completion routine will or MIMIO_TXDONE in with txflags). - */ - timeout = HZ; - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&mimio->waitq, &wait); - - while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) { - timeout = schedule_timeout(timeout); - rmb(); - } - - if ((mimio->txflags & MIMIO_TXDONE) == 0) - dev_dbg(&mimio->idev->dev, "tx timed out.\n"); - - /* - * Now that completion has been signalled, - * unlink the urb so that it can be recycled. - */ - set_current_state(TASK_RUNNING); - remove_wait_queue(&mimio->waitq, &wait); - usb_unlink_urb(mimio->out.urb); - - return rslt; -} - -static int __init mimio_init(void) -{ - int rslt; - - rslt = usb_register(&mimio_driver); - if (rslt != 0) { - err("%s: usb_register failure: %d", __func__, rslt); - return rslt; - } - - printk(KERN_INFO KBUILD_MODNAME ":" - DRIVER_DESC " " DRIVER_VERSION "\n"); - return rslt; -} - -static void __exit mimio_exit(void) -{ - usb_deregister(&mimio_driver); -} - -module_init(mimio_init); -module_exit(mimio_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 4ce399b6d237..c39a25f500ef 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -2181,6 +2181,7 @@ int panel_init(void) if (pprt) { parport_release(pprt); parport_unregister_device(pprt); + pprt = NULL; } parport_unregister_driver(&panel_driver); printk(KERN_ERR "Panel driver version " PANEL_VERSION @@ -2230,6 +2231,7 @@ static void __exit panel_cleanup_module(void) /* TODO: free all input signals */ parport_release(pprt); parport_unregister_device(pprt); + pprt = NULL; } parport_unregister_driver(&panel_driver); } diff --git a/drivers/staging/rk29/ipp/Kconfig b/drivers/staging/rk29/ipp/Kconfig new file mode 100644 index 000000000000..f7599165d96c --- /dev/null +++ b/drivers/staging/rk29/ipp/Kconfig @@ -0,0 +1,8 @@ +menu "IPP" +config RK29_IPP + tristate "ROCKCHIP RK29 IPP" + default y + help + rk29 ipp module. +endmenu + diff --git a/drivers/staging/rk29/ipp/Makefile b/drivers/staging/rk29/ipp/Makefile new file mode 100644 index 000000000000..674c218582e7 --- /dev/null +++ b/drivers/staging/rk29/ipp/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the ipp. +# + +obj-$(CONFIG_RK29_IPP) += rk29-ipp.o +rk29ipp-objs := rk29-ipp.o \ No newline at end of file diff --git a/drivers/staging/rk29/ipp/rk29-ipp.c b/drivers/staging/rk29/ipp/rk29-ipp.c new file mode 100644 index 000000000000..bdf1f6c1ac70 --- /dev/null +++ b/drivers/staging/rk29/ipp/rk29-ipp.c @@ -0,0 +1,939 @@ +/* drivers/staging/rk29/ipp/rk29-ipp.c + * + * Copyright (C) 2010 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#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 + + +struct ipp_drvdata { + struct miscdevice miscdev; + struct device dev; + void *ipp_base; + struct ipp_regs regs; + int irq0; + struct clk *axi_clk; + struct clk *ahb_clk; + struct mutex mutex; // mutex +}; + +static struct ipp_drvdata *drvdata = NULL; + +static DECLARE_WAIT_QUEUE_HEAD(wait_queue); +static int wq_condition = 0; + +/* Context data (unique) */ +struct ipp_context +{ + struct ipp_drvdata *data; // driver data + struct rk29_ipp_req *blit; // blit request + uint32_t rot; // rotation mode + struct file *srcf; // source file (for PMEM) + struct file *dstf; // destination file (for PMEM) +}; + +#define IPP_MAJOR 232 +#define RK_IPP_BLIT 0x5017 +#define RK_IPP_SYNC 0x5018 + +#define RK29_IPP_PHYS 0x10110000 +#define RK29_IPP_SIZE SZ_16K +#define IPP_RESET_TIMEOUT 1000 + +/* Driver information */ +#define DRIVER_DESC "RK29 IPP Device Driver" +#define DRIVER_NAME "rk29-ipp" + +/* Logging */ +#define IPP_DEBUG 0 +#ifdef IPP_DEBUG +#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define ERR(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define WARNING(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#define INFO(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) +#else +#define DBG(format, args...) +#define ERR(format, args...) +#define WARNING(format, args...) +#define INFO(format, args...) +#endif + +static inline void ipp_write( uint32_t b, uint32_t r) +{ + __raw_writel(b, drvdata->ipp_base + r); +} + +static inline uint32_t ipp_read( uint32_t r) +{ + return __raw_readl(drvdata->ipp_base + r); +} + +static void ipp_soft_reset(void) +{ + uint32_t i; + uint32_t reg; + + ipp_write(1, IPP_SRESET); + + for(i = 0; i < IPP_RESET_TIMEOUT; i++) { + reg = ipp_read( IPP_SRESET) & 1; + + if(reg == 0) + break; + + udelay(1); + } + + if(i == IPP_RESET_TIMEOUT) + ERR("soft reset timeout.\n"); +} + +int ipp_do_blit(struct rk29_ipp_req *req) +{ + uint32_t rotate; + uint32_t pre_scale = 0; + uint32_t post_scale = 0; + uint32_t pre_scale_w, pre_scale_h; + uint32_t post_scale_w = 0x1000; + uint32_t post_scale_h = 0x1000; + uint32_t pre_scale_target_w=0, pre_scale_target_h=0; + uint32_t post_scale_target_w, post_scale_target_h; + uint32_t dst0_YrgbMst=0,dst0_CbrMst=0; + uint32_t ret = 0; + rotate = req->flag; + switch (rotate) { + case IPP_ROT_90: + //for rotation 90 degree + DBG("rotate %d, src0.fmt %d",rotate,req->src0.fmt); + switch(req->src0.fmt) + { + case IPP_XRGB_8888: + dst0_YrgbMst = req->dst0.YrgbMst + req->dst0.w*4; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_RGB_565: + dst0_YrgbMst = req->dst0.YrgbMst + req->dst0.w*2; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_Y_CBCR_H1V1: + dst0_YrgbMst = req->dst0.YrgbMst + req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst + req->dst0.w*2; + break; + + case IPP_Y_CBCR_H2V1: + dst0_YrgbMst = req->dst0.YrgbMst + req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst + req->dst0.w*2; + break; + + case IPP_Y_CBCR_H2V2: + dst0_YrgbMst = req->dst0.YrgbMst+ req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst + req->dst0.w; + break; + + default: + + break; + } + break; + + case IPP_ROT_180: + //for rotation 180 degree + DBG("rotate %d, src0.fmt %d",rotate,req->src0.fmt); + switch(req->src0.fmt) + { + case IPP_XRGB_8888: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w*4+req->dst0.w*4; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_RGB_565: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w*2+req->dst0.w*2; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_Y_CBCR_H1V1: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w+req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst+(req->dst0.h-1)*req->dst_vir_w*2+req->dst0.w*2; + break; + + case IPP_Y_CBCR_H2V1: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w+req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst+(req->dst0.h-1)*req->dst_vir_w+req->dst0.w; + break; + + case IPP_Y_CBCR_H2V2: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w+req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst+((req->dst0.h/2)-1)*req->dst_vir_w+req->dst0.w; + break; + + default: + break; + } + break; + + case IPP_ROT_270: + DBG("rotate %d, src0.fmt %d \n",rotate,req->src0.fmt); + switch(req->src0.fmt) + { + case IPP_XRGB_8888: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w*4; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_RGB_565: + dst0_YrgbMst = req->dst0.YrgbMst +(req->dst0.h-1)*req->dst_vir_w*2; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_Y_CBCR_H1V1: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w; + dst0_CbrMst = req->dst0.CbrMst+(req->dst0.h-1)*req->dst_vir_w*2; + break; + + case IPP_Y_CBCR_H2V1: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w; + dst0_CbrMst = req->dst0.CbrMst+(req->dst0.h-1)*req->dst_vir_w*2; + break; + + case IPP_Y_CBCR_H2V2: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w; + dst0_CbrMst = req->dst0.CbrMst+((req->dst0.h/2)-1)*req->dst_vir_w; + break; + + default: + break; + } + break; + + case IPP_ROT_X_FLIP: + DBG("rotate %d, src0.fmt %d",rotate,req->src0.fmt); + switch(req->src0.fmt) + { + case IPP_XRGB_8888: + dst0_YrgbMst = req->dst0.YrgbMst+req->dst0.w*4; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_RGB_565: + dst0_YrgbMst = req->dst0.YrgbMst+req->dst0.w*2; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_Y_CBCR_H1V1: + dst0_YrgbMst = req->dst0.YrgbMst+req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst+req->dst0.w*2; + break; + + case IPP_Y_CBCR_H2V1: + dst0_YrgbMst = req->dst0.YrgbMst+req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst+req->dst0.w; + break; + + case IPP_Y_CBCR_H2V2: + dst0_YrgbMst = req->dst0.YrgbMst+req->dst0.w; + dst0_CbrMst = req->dst0.CbrMst+req->dst0.w; + break; + + default: + break; + } + + break; + + case IPP_ROT_Y_FLIP: + DBG("rotate %d, src0.fmt %d",rotate,req->src0.fmt); + switch(req->src0.fmt) + { + case IPP_XRGB_8888: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w*4; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_RGB_565: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w*2; + dst0_CbrMst = req->dst0.CbrMst; + break; + + case IPP_Y_CBCR_H1V1: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w; + dst0_CbrMst = req->dst0.CbrMst+(req->dst0.h-1)*req->dst_vir_w*2; + break; + + case IPP_Y_CBCR_H2V1: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w; + dst0_CbrMst = req->dst0.CbrMst+(req->dst0.h-1)*req->dst_vir_w; + break; + + case IPP_Y_CBCR_H2V2: + dst0_YrgbMst = req->dst0.YrgbMst+(req->dst0.h-1)*req->dst_vir_w; + dst0_CbrMst = req->dst0.CbrMst+((req->dst0.h/2)-1)*req->dst_vir_w; + break; + + default: + break; + } + + break; + case IPP_ROT_0: + //for 0 degree + DBG("rotate %d, src0.fmt %d",rotate,req->src0.fmt); + dst0_YrgbMst = req->dst0.YrgbMst; + dst0_CbrMst = req->dst0.CbrMst; + break; + + default: + ERR("ipp is not surpport degree!!\n" ); + break; + } + + if(drvdata->axi_clk) + { + clk_enable(drvdata->axi_clk); + } + else + { + printk("axi_clk is null \n"); + ret = -EINVAL; + goto error_axi_clk; + } + + if(drvdata->ahb_clk) + { + clk_enable(drvdata->ahb_clk); + } + else + { + printk("ahb_clk is null \n"); + ret = -EINVAL; + goto error_ahb_clk; + } + + /* Configure source image */ + DBG("src YrgbMst 0x%x , CbrMst0x%x, %dx%d, fmt = %d\n", req->src0.YrgbMst,req->src0.CbrMst, + req->src0.w, req->src0.h, req->src0.fmt); + + ipp_write(req->src0.YrgbMst, IPP_SRC0_Y_MST); + if(IS_YCRCB(req->src0.fmt)) + { + ipp_write(req->src0.CbrMst, IPP_SRC0_CBR_MST); + } + ipp_write(req->src0.h<<16|req->src0.w, IPP_SRC_IMG_INFO); + ipp_write((ipp_read(IPP_CONFIG)&(~0x7))|req->src0.fmt, IPP_CONFIG); + + /* Configure destination image */ + DBG("dst YrgbMst 0x%x , CbrMst0x%x, %dx%d\n", dst0_YrgbMst,dst0_CbrMst, + req->dst0.w, req->dst0.h); + + ipp_write(dst0_YrgbMst, IPP_DST0_Y_MST); + + if(IS_YCRCB(req->src0.fmt)) + { + ipp_write(dst0_CbrMst, IPP_DST0_CBR_MST); + } + ipp_write(req->dst0.h<<16|req->dst0.w, IPP_DST_IMG_INFO); + + /*Configure Pre_scale*/ + if((IPP_ROT_90 == rotate) || (IPP_ROT_270 == rotate)) + { + pre_scale = ((req->dst0.w < req->src0.h) ? 1 : 0)||((req->dst0.h < req->src0.w) ? 1 : 0); + } + else //other degree + { + pre_scale = ((req->dst0.w < req->src0.w) ? 1 : 0)||((req->dst0.h < req->src0.h) ? 1 : 0); + } + + if(pre_scale) + { + if(((IPP_ROT_90 == rotate) || (IPP_ROT_270 == rotate))) + { + + if((req->src0.w>req->dst0.h)) + { + pre_scale_w = (uint32_t)( req->src0.w/req->dst0.h);//floor + } + else + { + pre_scale_w = 1; + } + if((req->src0.h>req->dst0.w)) + { + pre_scale_h = (uint32_t)( req->src0.h/req->dst0.w);//floor + } + else + { + pre_scale_h = 1; + } + + DBG("!!!!!pre_scale_h %d,pre_scale_w %d \n",pre_scale_h,pre_scale_w); + + ipp_write((ipp_read(IPP_CONFIG)&0xffffffef)|PRE_SCALE, IPP_CONFIG); //enable pre_scale + ipp_write((pre_scale_h-1)<<3|(pre_scale_w-1),IPP_PRE_SCL_PARA); + + if((req->src0.w%pre_scale_w)!=0) //ÏòÉÏÈ¡Õû ceil + { + pre_scale_target_w = req->src0.w/pre_scale_w+1; + } + else + { + pre_scale_target_w = req->src0.w/pre_scale_w; + } + + if((req->src0.h%pre_scale_h)!=0)//ÏòÉÏÈ¡Õû ceil + { + pre_scale_target_h = req->src0.h/pre_scale_h +1; + } + else + { + pre_scale_target_h = req->src0.h/pre_scale_h; + } + + ipp_write(((pre_scale_target_h)<<16)|(pre_scale_target_w), IPP_PRE_IMG_INFO); + + } + else//0 180 x ,y + { + + if((req->src0.w>req->dst0.w)) + { + pre_scale_w = (uint32_t)( req->src0.w/req->dst0.w);//floor + } + else + { + pre_scale_w = 1; + } + + if((req->src0.h>req->dst0.h)) + { + pre_scale_h = (uint32_t)( req->src0.h/req->dst0.h);//floor + } + else + { + pre_scale_h = 1; + } + + DBG("!!!!!pre_scale_h %d,pre_scale_w %d \n",pre_scale_h,pre_scale_w); + + ipp_write((ipp_read(IPP_CONFIG)&0xffffffef)|PRE_SCALE, IPP_CONFIG); //enable pre_scale + ipp_write((pre_scale_h-1)<<3|(pre_scale_w-1),IPP_PRE_SCL_PARA); + + if((req->src0.w%pre_scale_w)!=0) //ÏòÉÏÈ¡Õû ceil + { + pre_scale_target_w = req->src0.w/pre_scale_w+1; + } + else + { + pre_scale_target_w = req->src0.w/pre_scale_w; + } + + if((req->src0.h%pre_scale_h)!=0)//ÏòÉÏÈ¡Õû ceil + { + pre_scale_target_h = req->src0.h/pre_scale_h +1; + } + else + { + pre_scale_target_h = req->src0.h/pre_scale_h; + } + } + ipp_write(((pre_scale_target_h)<<16)|(pre_scale_target_w), IPP_PRE_IMG_INFO); + + } + else//no pre_scale + { + ipp_write(0,IPP_PRE_SCL_PARA); + ipp_write((req->src0.h<<16)|req->src0.w, IPP_PRE_IMG_INFO); + } + + /*Configure Post_scale*/ + if((IPP_ROT_90 == rotate) || (IPP_ROT_270 == rotate)) + { + if (( (req->src0.h%req->dst0.w)!=0)||( (req->src0.w%req->dst0.h)!= 0)//СÊý±¶ËõС + ||(req->dst0.w > req->src0.h) ||(req->dst0.h > req->src0.w)) + { + post_scale = 1; + } + else + { + post_scale = 0; + } + } + else //0 180 x-flip y-flip + { + if (( (req->src0.w%req->dst0.w)!=0)||( (req->src0.h%req->dst0.h)!= 0)//СÊý±¶ËõС + ||(req->dst0.w > req->src0.w) ||(req->dst0.h > req->src0.h)) + { + post_scale = 1; + } + else + { + post_scale = 0; + } + } + + if(post_scale) + { + if((IPP_ROT_90 == rotate) || (IPP_ROT_270 == rotate)) + { + if(pre_scale) + { + post_scale_target_w = pre_scale_target_w; + post_scale_target_h = pre_scale_target_h; + } + else + { + post_scale_target_w = req->src0.w; + post_scale_target_h = req->src0.h; + } + + DBG("post_scale_target_w %d ,post_scale_target_h %d !!!\n",post_scale_target_w,post_scale_target_h); + + switch(req->src0.fmt) + { + case IPP_XRGB_8888: + case IPP_RGB_565: + case IPP_Y_CBCR_H1V1: + post_scale_w = (uint32_t)(4096*(post_scale_target_w-1)/(req->dst0.h-1)); + break; + + case IPP_Y_CBCR_H2V1: + case IPP_Y_CBCR_H2V2: + post_scale_w = (uint32_t)(4096*(post_scale_target_w/2-1)/(req->dst0.h/2-1)); + break; + + default: + break; + } + post_scale_h = (uint32_t)(4096*(post_scale_target_h -1)/(req->dst0.w-1)); + + DBG("1111 post_scale_w %x,post_scale_h %x!!! \n",post_scale_w,post_scale_h); + } + else// 0 180 x-flip y-flip + { + + if(pre_scale) + { + post_scale_target_w = pre_scale_target_w; + post_scale_target_h = pre_scale_target_h; + } + else + { + post_scale_target_w = req->src0.w; + post_scale_target_h = req->src0.h; + } + + switch(req->src0.fmt) + { + case IPP_XRGB_8888: + case IPP_RGB_565: + case IPP_Y_CBCR_H1V1: + post_scale_w = (uint32_t)(4096*(post_scale_target_w-1)/(req->dst0.w-1)); + break; + + case IPP_Y_CBCR_H2V1: + case IPP_Y_CBCR_H2V2: + post_scale_w = (uint32_t)(4096*(post_scale_target_w/2-1)/(req->dst0.w/2-1)); + break; + + default: + break; + } + post_scale_h = (uint32_t)(4096*(post_scale_target_h -1)/(req->dst0.h-1)); + + } + ipp_write((ipp_read(IPP_CONFIG)&0xfffffff7)|POST_SCALE, IPP_CONFIG); //enable post_scale + ipp_write((post_scale_h<<16)|post_scale_w, IPP_POST_SCL_PARA); + } + else //no post_scale + { + DBG("no post_scale !!!!!! \n"); + ipp_write(ipp_read(IPP_CONFIG)&(~POST_SCALE), IPP_CONFIG); //disable post_scale + ipp_write((post_scale_h<<16)|post_scale_w, IPP_POST_SCL_PARA); + } + + /* Configure rotation */ + + if(IPP_ROT_0 == req->flag) + { + ipp_write(ipp_read(IPP_CONFIG)&(~ROT_ENABLE), IPP_CONFIG); + } + else if(req->flag > IPP_ROT_LIMIT) + { + printk("rk29_ipp is not surpport rot degree!!!!\n"); + ret = -1; + goto error_rot_limit; + } + else + { + ipp_write(ipp_read(IPP_CONFIG)|ROT_ENABLE, IPP_CONFIG); + ipp_write(ipp_read(IPP_CONFIG)|rotate<<5, IPP_CONFIG); + } + + /*Configure other*/ + ipp_write((req->dst_vir_w<<16)|req->src_vir_w, IPP_IMG_VIR); + + if((req->src0.w%4) !=0) + ipp_write(ipp_read(IPP_CONFIG)|(1<<26), IPP_CONFIG);//store clip mode + + /* Start the operation */ + + ipp_write(8, IPP_INT);// + + //msleep(5000);//debug use + + ipp_write(1, IPP_PROCESS_ST); + + if(!wait_event_timeout(wait_queue, wq_condition, msecs_to_jiffies(req->timeout))) + { + printk("%s wait_event_timeout \n",__FUNCTION__); + wq_condition = 0; + if(!drvdata) + { + printk("close clk 0! \n"); + ret = -EINVAL; + goto error_null; + } + ret = -EAGAIN; + goto errot_timeout; + } + + wq_condition = 0; + + if(!drvdata) + { + printk("close clk! \n"); + ret = -EINVAL; + goto error_null; + } + + if(((ipp_read(IPP_INT)>>6)&0x3) ==0)// idle + { + clk_disable(drvdata->axi_clk); + clk_disable(drvdata->ahb_clk); + } + else + { + printk("rk29 ipp status is error!!!\n"); + ret = -EINVAL; + goto errot_timeout; + } + return 0; + +error_null: +errot_timeout: +error_rot_limit: +error_ahb_clk: + clk_disable(drvdata->ahb_clk); +error_axi_clk: + clk_disable(drvdata->axi_clk); + return ret; +} + +static int stretch_blit(struct ipp_context *ctx, unsigned long arg ) +{ + struct ipp_drvdata *data = ctx->data; + int ret = 0; + struct rk29_ipp_req req; + + mutex_lock(&data->mutex); + + if (unlikely(copy_from_user(&req, (struct rk29_ipp_req*)arg, + sizeof(struct rk29_ipp_req)))) { + ERR("copy_from_user failed\n"); + ret = -EFAULT; + goto err_noput; + } + + if (unlikely((req.src0.w <= 1) || (req.src0.h <= 1))) { + ERR("invalid source resolution\n"); + ret = -EINVAL; + goto err_noput; + } + + if (unlikely((req.dst0.w <= 1) || (req.dst0.h <= 1))) { + ERR("invalid destination resolution\n"); + ret = -EINVAL; + goto err_noput; + } + + if (unlikely(req.src0.YrgbMst== 0) ) + { + ERR("could not retrieve src image from memory\n"); + ret = -EINVAL; + goto err_noput; + } + + if (unlikely(req.dst0.YrgbMst== 0) ) + { + ERR("could not retrieve dst image from memory\n"); + ret = -EINVAL; + goto err_noput; + } + + ret = ipp_do_blit(&req); + if(ret != 0) { + ERR("Failed to start IPP operation (%d)\n", ret); + ipp_soft_reset(); + goto err_noput; + } + +err_noput: + + mutex_unlock(&data->mutex); + + return ret; +} + +static int ipp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + + struct ipp_context *ctx = (struct ipp_context *)file->private_data; + int ret = 0; + switch (cmd) + { + case RK_IPP_BLIT: + ret = stretch_blit(ctx, arg); + break; + + default: + ERR("unknown ioctl cmd!\n"); + ret = -EINVAL; + break; + } + return ret; +} + +static int rk29_ipp_open(struct inode *inode, struct file *file) +{ + struct ipp_context *ctx; + + ctx = kmalloc(sizeof(struct ipp_context), GFP_KERNEL); + if (ctx == NULL) { + ERR("Context allocation failed\n"); + return -ENOMEM; + } + + memset(ctx, 0, sizeof(struct ipp_context)); + ctx->data = drvdata; + ctx->rot = IPP_ROT_0; + file->private_data = ctx; + + DBG("device opened\n"); + + return 0; +} + +static int ipp_release(struct inode *inode, struct file *file) +{ + struct ipp_context *ctx = (struct ipp_context *)file->private_data; + kfree(ctx); + + DBG("device released\n"); + return 0; +} + +static irqreturn_t rk29_ipp_irq(int irq, void *dev_id) +{ + uint32_t stat; + + DBG("rk29_ipp_irq %d \n",irq); + stat = ipp_read(IPP_INT); + + while(!(stat & 0x1)) + { + DBG("stat %d \n",stat); + } + wq_condition = 1; + wake_up(&wait_queue); + + ipp_write(ipp_read(IPP_INT)|0xc, IPP_INT); + ipp_write(ipp_read(IPP_INT)|0x30, IPP_INT); + return IRQ_HANDLED; +} + +struct file_operations ipp_fops = { + .owner = THIS_MODULE, + .open = rk29_ipp_open, + .release = ipp_release, + .ioctl = ipp_ioctl, +}; + +static struct miscdevice ipp_dev ={ + .minor = IPP_MAJOR, + .name = "rk29-ipp", + .fops = &ipp_fops, +}; + +static int __init ipp_drv_probe(struct platform_device *pdev) +{ + struct ipp_drvdata *data; + int ret = 0; + + data = kmalloc(sizeof(struct ipp_drvdata), GFP_KERNEL); + if(NULL==data) + { + ERR("failed to allocate driver data.\n"); + return -ENOMEM; + } + + /* get the clock */ + data->axi_clk = clk_get(&pdev->dev, "ipp_axi"); + if(NULL == data->axi_clk) + { + ERR("failed to find ipp axi clock source\n"); + ret = -ENOENT; + goto err_clock; + } + + data->ahb_clk = clk_get(&pdev->dev, "ipp_ahb"); + if(NULL == data->ahb_clk) + { + ERR("failed to find ipp ahb clock source\n"); + ret = -ENOENT; + goto err_clock; + } + + /* map the memory */ + data->ipp_base = (void*)ioremap( RK29_IPP_PHYS, SZ_16K);//ipp size 16k + if (data->ipp_base == NULL) + { + ERR("ioremap failed\n"); + ret = -ENOENT; + goto err_ioremap; + } + + /* get the IRQ */ + data->irq0 = pdev->resource[1].start; + printk("ipp irq %d\n",data->irq0); + if (data->irq0 <= 0) + { + ERR("failed to get irq resource (%d).\n", data->irq0); + ret = data->irq0; + goto err_irq; + } + + /* request the IRQ */ + ret = request_irq(data->irq0, rk29_ipp_irq, IRQF_SHARED, "rk29-ipp", pdev); + if (ret) + { + ERR("request_irq failed (%d).\n", ret); + goto err_irq; + } + + mutex_init(&data->mutex); + + platform_set_drvdata(pdev, data); + drvdata = data; + + ret = misc_register(&ipp_dev); + if(ret) + { + ERR("cannot register miscdev (%d)\n", ret); + goto err_misc_register; + } + DBG("Driver loaded succesfully\n"); + + return 0; + +err_misc_register: + free_irq(data->irq0, pdev); +err_irq: + iounmap(data->ipp_base); +err_ioremap: +err_clock: + kfree(data); + + return ret; +} + +static int ipp_drv_remove(struct platform_device *pdev) +{ + struct ipp_drvdata *data = platform_get_drvdata(pdev); + DBG("%s [%d]\n",__FUNCTION__,__LINE__); + + misc_deregister(&(data->miscdev)); + free_irq(data->irq0, &data->miscdev); + iounmap((void __iomem *)(data->ipp_base)); + + if(data->axi_clk) { + clk_put(data->axi_clk); + } + if(data->ahb_clk) { + clk_put(data->ahb_clk); + } + + kfree(data); + return 0; +} + +static struct platform_driver rk29_ipp_driver = { + .probe = ipp_drv_probe, + .remove = ipp_drv_remove, + .driver = { + .owner = THIS_MODULE, + .name = "rk29-ipp", + }, +}; + +static int __init rk29_ipp_init(void) +{ + int ret; + + if ((ret = platform_driver_register(&rk29_ipp_driver)) != 0) + { + ERR("Platform device register failed (%d).\n", ret); + return ret; + } + INFO("Module initialized.\n"); + return 0; +} + +static void __exit rk29_ipp_exit(void) +{ + platform_driver_unregister(&rk29_ipp_driver); +} + +module_init(rk29_ipp_init); +module_exit(rk29_ipp_exit); + +/* Module information */ +MODULE_AUTHOR("wy@rock-chips.com"); +MODULE_DESCRIPTION("Driver for rk29 ipp device"); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/staging/rk29/vivante/Makefile b/drivers/staging/rk29/vivante/Makefile index e4171f01ac18..1bec4a3a706d 100644 --- a/drivers/staging/rk29/vivante/Makefile +++ b/drivers/staging/rk29/vivante/Makefile @@ -72,7 +72,7 @@ SDK_DIR ?= $(AQROOT)/build/sdk USE_3D_VG = 1 DEBUG = 0 -gcdkREPORT_VIDMEM_USAGE = 1 +gcdkREPORT_VIDMEM_USAGE = 0 #DRIVER_OUT_DIR = hal/driver #KERNEL_DIR ?= $(TOOL_DIR)/kernel diff --git a/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h b/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h index b6f830f62b72..ede2d686e389 100644 --- a/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h +++ b/drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h @@ -182,7 +182,7 @@ Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of virtual data. */ -#define gcdMMU_SIZE (128 << 10) +#define gcdMMU_SIZE (256 << 10) /* gcdSECURE_USER diff --git a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c index 7da7bec0e726..582cb7dd2e6d 100644 --- a/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c +++ b/drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c @@ -40,6 +40,12 @@ #define _GC_OBJ_ZONE gcvZONE_OS +#define PAGE_ALLOC_LIMIT 1 // ÏÞÖÆPageÉêÇëÊý + +#if PAGE_ALLOC_LIMIT +int g_pages_alloced = 0; +#endif + #define MEMORY_LOCK(os) \ gcmkVERIFY_OK(gckOS_AcquireMutex( \ (os), \ @@ -2656,7 +2662,20 @@ gceSTATUS gckOS_AllocatePagedMemoryEx( if (Contiguous) { +#if PAGE_ALLOC_LIMIT + if((g_pages_alloced + numPages) > 256*32) { + //printk("full %d! \n", g_pages_alloced); + addr = NULL; + } else { + addr = (char *)__get_free_pages(GFP_ATOMIC | GFP_DMA, GetOrder(numPages)); + if(addr) { + g_pages_alloced += numPages; + //printk("alloc %d / %d \n", numPages, g_pages_alloced); + } + } +#else addr = (char *)__get_free_pages(GFP_ATOMIC | GFP_DMA, GetOrder(numPages)); +#endif } else { @@ -2809,6 +2828,11 @@ gceSTATUS gckOS_FreePagedMemory( if (mdl->contiguous) { free_pages((unsigned long)mdl->addr, GetOrder(mdl->numPages)); +#if PAGE_ALLOC_LIMIT + g_pages_alloced -= mdl->numPages; + //printk("free %d / %d \n", mdl->numPages, g_pages_alloced); + if(g_pages_alloced<0) g_pages_alloced = 0; +#endif } else { diff --git a/drivers/staging/rt2860/common/2860_rtmp_init.c b/drivers/staging/rt2860/common/2860_rtmp_init.c index 0bc0fb99d2e4..98b0f8e726fa 100644 --- a/drivers/staging/rt2860/common/2860_rtmp_init.c +++ b/drivers/staging/rt2860/common/2860_rtmp_init.c @@ -716,7 +716,7 @@ VOID RTMPFreeTxRxRingMemory( { if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket)) { - PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); + PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS); } } diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index cd07059b25b5..c30773b5c59e 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -356,8 +356,12 @@ HwHSSIThreeWire( } udelay(10); } - if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) - panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp); + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) { + printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:" + " %#X RE|WE bits are not clear!!\n", u1bTmp); + dump_stack(); + return 0; + } // RTL8187S HSSI Read/Write Function u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); @@ -397,13 +401,23 @@ HwHSSIThreeWire( int idx; int ByteCnt = nDataBufBitCnt / 8; //printk("%d\n",nDataBufBitCnt); - if ((nDataBufBitCnt % 8) != 0) - panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n", - nDataBufBitCnt); + if ((nDataBufBitCnt % 8) != 0) { + printk(KERN_ERR "rtl8187se: " + "HwThreeWire(): nDataBufBitCnt(%d)" + " should be multiple of 8!!!\n", + nDataBufBitCnt); + dump_stack(); + nDataBufBitCnt += 8; + nDataBufBitCnt &= ~7; + } - if (nDataBufBitCnt > 64) - panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n", - nDataBufBitCnt); + if (nDataBufBitCnt > 64) { + printk(KERN_ERR "rtl8187se: HwThreeWire():" + " nDataBufBitCnt(%d) should <= 64!!!\n", + nDataBufBitCnt); + dump_stack(); + nDataBufBitCnt = 64; + } for(idx = 0; idx < ByteCnt; idx++) { diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 66274d7666ff..6d52d6adbb41 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -112,20 +112,25 @@ u32 rt_global_debug_component = \ static struct usb_device_id rtl8192_usb_id_tbl[] = { /* Realtek */ + {USB_DEVICE(0x0bda, 0x8171)}, {USB_DEVICE(0x0bda, 0x8192)}, {USB_DEVICE(0x0bda, 0x8709)}, /* Corega */ {USB_DEVICE(0x07aa, 0x0043)}, /* Belkin */ {USB_DEVICE(0x050d, 0x805E)}, + {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */ /* Sitecom */ {USB_DEVICE(0x0df6, 0x0031)}, + {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */ /* EnGenius */ {USB_DEVICE(0x1740, 0x9201)}, /* Dlink */ {USB_DEVICE(0x2001, 0x3301)}, /* Zinwell */ {USB_DEVICE(0x5a57, 0x0290)}, + /* Guillemot */ + {USB_DEVICE(0x06f8, 0xe031)}, //92SU {USB_DEVICE(0x0bda, 0x8172)}, {} diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c index 6da1021e8a65..af3832b03e4b 100644 --- a/drivers/staging/usbip/usbip_event.c +++ b/drivers/staging/usbip/usbip_event.c @@ -38,21 +38,13 @@ static int event_handler(struct usbip_device *ud) ud->eh_ops.shutdown(ud); ud->event &= ~USBIP_EH_SHUTDOWN; - - break; } - /* Stop the error handler. */ - if (ud->event & USBIP_EH_BYE) - return -1; - /* Reset the device. */ if (ud->event & USBIP_EH_RESET) { ud->eh_ops.reset(ud); ud->event &= ~USBIP_EH_RESET; - - break; } /* Mark the device as unusable. */ @@ -60,13 +52,11 @@ static int event_handler(struct usbip_device *ud) ud->eh_ops.unusable(ud); ud->event &= ~USBIP_EH_UNUSABLE; - - break; } - /* NOTREACHED */ - printk(KERN_ERR "%s: unknown event\n", __func__); - return -1; + /* Stop the error handler. */ + if (ud->event & USBIP_EH_BYE) + return -1; } return 0; @@ -117,6 +107,9 @@ void usbip_stop_eh(struct usbip_device *ud) { struct usbip_task *eh = &ud->eh; + if (eh->thread == current) + return; /* do not wait for myself */ + wait_for_completion(&eh->thread_done); usbip_dbg_eh("usbip_eh has finished\n"); } diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 6e91fc2bd850..c2018029059c 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -163,6 +163,8 @@ void rh_port_disconnect(int rhport) * spin_unlock(&vdev->ud.lock); */ spin_unlock_irqrestore(&the_controller->lock, flags); + + usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); } diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 53450b48eaa6..269d1e2382b7 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1089,11 +1089,13 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent) } //2008-07-21-01by MikeLiu //register wpadev +#if 0 if(wpa_set_wpadev(pDevice, 1)!=0) { printk("Fail to Register WPADEV?\n"); unregister_netdev(pDevice->dev); free_netdev(dev); } +#endif device_print_info(pDevice); pci_set_drvdata(pcid, pDevice); return 0; diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 574e0b0a9c28..a078f6f50d70 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -767,9 +767,14 @@ static int wpa_set_associate(PSDevice pDevice, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); - if (param->u.wpa_associate.wpa_ie && - copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) - return -EINVAL; + if (param->u.wpa_associate.wpa_ie_len) { + if (!param->u.wpa_associate.wpa_ie) + return -EINVAL; + if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE)) + return -EINVAL; + if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) + return -EFAULT; + } if (param->u.wpa_associate.mode == 1) pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index d171b563e94c..ae2c0c06dd37 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2259,7 +2259,7 @@ static ssize_t reboot(struct device *dev, struct device_attribute *attr, return ret; } -static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); +static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot); static ssize_t read_human_status(struct device *dev, struct device_attribute *attr, char *buf) @@ -2322,7 +2322,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at return ret; } -static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL); +static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL); static ssize_t read_delin(struct device *dev, struct device_attribute *attr, char *buf) @@ -2354,7 +2354,7 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, return ret; } -static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); +static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL); #define UEA_ATTR(name, reset) \ \ diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e4eca7810bcf..e3017c46d5ec 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -170,6 +170,7 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb) { wb->use = 0; acm->transmitting--; + usb_autopm_put_interface_async(acm->control); } /* @@ -211,9 +212,12 @@ static int acm_write_start(struct acm *acm, int wbn) } dbg("%s susp_count: %d", __func__, acm->susp_count); + usb_autopm_get_interface_async(acm->control); if (acm->susp_count) { - acm->delayed_wb = wb; - schedule_work(&acm->waker); + if (!acm->delayed_wb) + acm->delayed_wb = wb; + else + usb_autopm_put_interface_async(acm->control); spin_unlock_irqrestore(&acm->write_lock, flags); return 0; /* A white lie */ } @@ -534,23 +538,6 @@ static void acm_softint(struct work_struct *work) tty_kref_put(tty); } -static void acm_waker(struct work_struct *waker) -{ - struct acm *acm = container_of(waker, struct acm, waker); - int rv; - - rv = usb_autopm_get_interface(acm->control); - if (rv < 0) { - dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__); - return; - } - if (acm->delayed_wb) { - acm_start_wb(acm, acm->delayed_wb); - acm->delayed_wb = NULL; - } - usb_autopm_put_interface(acm->control); -} - /* * TTY handlers */ @@ -984,7 +971,8 @@ static int acm_probe(struct usb_interface *intf, } if (!buflen) { - if (intf->cur_altsetting->endpoint->extralen && + if (intf->cur_altsetting->endpoint && + intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { dev_dbg(&intf->dev, "Seeking extra descriptors on endpoint\n"); @@ -1178,7 +1166,6 @@ static int acm_probe(struct usb_interface *intf, acm->urb_task.func = acm_rx_tasklet; acm->urb_task.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint); - INIT_WORK(&acm->waker, acm_waker); init_waitqueue_head(&acm->drain_wait); spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); @@ -1215,7 +1202,7 @@ static int acm_probe(struct usb_interface *intf, if (rcv->urb == NULL) { dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); - goto alloc_fail7; + goto alloc_fail6; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -1239,7 +1226,7 @@ static int acm_probe(struct usb_interface *intf, if (snd->urb == NULL) { dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)"); - goto alloc_fail7; + goto alloc_fail8; } if (usb_endpoint_xfer_int(epwrite)) @@ -1278,6 +1265,7 @@ static int acm_probe(struct usb_interface *intf, i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate); if (i < 0) { + device_remove_file(&intf->dev, &dev_attr_wCountryCodes); kfree(acm->country_codes); goto skip_countries; } @@ -1314,6 +1302,7 @@ static int acm_probe(struct usb_interface *intf, usb_free_urb(acm->wb[i].urb); alloc_fail7: acm_read_buffers_free(acm); +alloc_fail6: for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->ru[i].urb); usb_free_urb(acm->ctrlurb); @@ -1343,7 +1332,6 @@ static void stop_data_traffic(struct acm *acm) tasklet_enable(&acm->urb_task); cancel_work_sync(&acm->work); - cancel_work_sync(&acm->waker); } static void acm_disconnect(struct usb_interface *intf) @@ -1435,6 +1423,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) static int acm_resume(struct usb_interface *intf) { struct acm *acm = usb_get_intfdata(intf); + struct acm_wb *wb; int rv = 0; int cnt; @@ -1449,6 +1438,21 @@ static int acm_resume(struct usb_interface *intf) mutex_lock(&acm->mutex); if (acm->port.count) { rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); + + spin_lock_irq(&acm->write_lock); + if (acm->delayed_wb) { + wb = acm->delayed_wb; + acm->delayed_wb = NULL; + spin_unlock_irq(&acm->write_lock); + acm_start_wb(acm, wb); + } else { + spin_unlock_irq(&acm->write_lock); + } + + /* + * delayed error checking because we must + * do the write path at all cost + */ if (rv < 0) goto err_out; @@ -1461,6 +1465,17 @@ static int acm_resume(struct usb_interface *intf) } #endif /* CONFIG_PM */ + +#define NOKIA_PCSUITE_ACM_INFO(x) \ + USB_DEVICE_AND_INTERFACE_INFO(0x0421, x, \ + USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ + USB_CDC_ACM_PROTO_VENDOR) + +#define SAMSUNG_PCSUITE_ACM_INFO(x) \ + USB_DEVICE_AND_INTERFACE_INFO(0x04e7, x, \ + USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ + USB_CDC_ACM_PROTO_VENDOR) + /* * USB driver structure. */ @@ -1518,6 +1533,76 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ }, + { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */ + .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ + }, + + /* Nokia S60 phones expose two ACM channels. The first is + * a modem and is picked up by the standard AT-command + * information below. The second is 'vendor-specific' but + * is treated as a serial device at the S60 end, so we want + * to expose it on Linux too. */ + { NOKIA_PCSUITE_ACM_INFO(0x042D), }, /* Nokia 3250 */ + { NOKIA_PCSUITE_ACM_INFO(0x04D8), }, /* Nokia 5500 Sport */ + { NOKIA_PCSUITE_ACM_INFO(0x04C9), }, /* Nokia E50 */ + { NOKIA_PCSUITE_ACM_INFO(0x0419), }, /* Nokia E60 */ + { NOKIA_PCSUITE_ACM_INFO(0x044D), }, /* Nokia E61 */ + { NOKIA_PCSUITE_ACM_INFO(0x0001), }, /* Nokia E61i */ + { NOKIA_PCSUITE_ACM_INFO(0x0475), }, /* Nokia E62 */ + { NOKIA_PCSUITE_ACM_INFO(0x0508), }, /* Nokia E65 */ + { NOKIA_PCSUITE_ACM_INFO(0x0418), }, /* Nokia E70 */ + { NOKIA_PCSUITE_ACM_INFO(0x0425), }, /* Nokia N71 */ + { NOKIA_PCSUITE_ACM_INFO(0x0486), }, /* Nokia N73 */ + { NOKIA_PCSUITE_ACM_INFO(0x04DF), }, /* Nokia N75 */ + { NOKIA_PCSUITE_ACM_INFO(0x000e), }, /* Nokia N77 */ + { NOKIA_PCSUITE_ACM_INFO(0x0445), }, /* Nokia N80 */ + { NOKIA_PCSUITE_ACM_INFO(0x042F), }, /* Nokia N91 & N91 8GB */ + { NOKIA_PCSUITE_ACM_INFO(0x048E), }, /* Nokia N92 */ + { NOKIA_PCSUITE_ACM_INFO(0x0420), }, /* Nokia N93 */ + { NOKIA_PCSUITE_ACM_INFO(0x04E6), }, /* Nokia N93i */ + { NOKIA_PCSUITE_ACM_INFO(0x04B2), }, /* Nokia 5700 XpressMusic */ + { NOKIA_PCSUITE_ACM_INFO(0x0134), }, /* Nokia 6110 Navigator (China) */ + { NOKIA_PCSUITE_ACM_INFO(0x046E), }, /* Nokia 6110 Navigator */ + { NOKIA_PCSUITE_ACM_INFO(0x002f), }, /* Nokia 6120 classic & */ + { NOKIA_PCSUITE_ACM_INFO(0x0088), }, /* Nokia 6121 classic */ + { NOKIA_PCSUITE_ACM_INFO(0x00fc), }, /* Nokia 6124 classic */ + { NOKIA_PCSUITE_ACM_INFO(0x0042), }, /* Nokia E51 */ + { NOKIA_PCSUITE_ACM_INFO(0x00b0), }, /* Nokia E66 */ + { NOKIA_PCSUITE_ACM_INFO(0x00ab), }, /* Nokia E71 */ + { NOKIA_PCSUITE_ACM_INFO(0x0481), }, /* Nokia N76 */ + { NOKIA_PCSUITE_ACM_INFO(0x0007), }, /* Nokia N81 & N81 8GB */ + { NOKIA_PCSUITE_ACM_INFO(0x0071), }, /* Nokia N82 */ + { NOKIA_PCSUITE_ACM_INFO(0x04F0), }, /* Nokia N95 & N95-3 NAM */ + { NOKIA_PCSUITE_ACM_INFO(0x0070), }, /* Nokia N95 8GB */ + { NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */ + { NOKIA_PCSUITE_ACM_INFO(0x0099), }, /* Nokia 6210 Navigator, RM-367 */ + { NOKIA_PCSUITE_ACM_INFO(0x0128), }, /* Nokia 6210 Navigator, RM-419 */ + { NOKIA_PCSUITE_ACM_INFO(0x008f), }, /* Nokia 6220 Classic */ + { NOKIA_PCSUITE_ACM_INFO(0x00a0), }, /* Nokia 6650 */ + { NOKIA_PCSUITE_ACM_INFO(0x007b), }, /* Nokia N78 */ + { NOKIA_PCSUITE_ACM_INFO(0x0094), }, /* Nokia N85 */ + { NOKIA_PCSUITE_ACM_INFO(0x003a), }, /* Nokia N96 & N96-3 */ + { NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */ + { NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */ + { NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */ + { NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */ + { NOKIA_PCSUITE_ACM_INFO(0x0178), }, /* Nokia E63 */ + { NOKIA_PCSUITE_ACM_INFO(0x010e), }, /* Nokia E75 */ + { NOKIA_PCSUITE_ACM_INFO(0x02d9), }, /* Nokia 6760 Slide */ + { NOKIA_PCSUITE_ACM_INFO(0x01d0), }, /* Nokia E52 */ + { NOKIA_PCSUITE_ACM_INFO(0x0223), }, /* Nokia E72 */ + { NOKIA_PCSUITE_ACM_INFO(0x0275), }, /* Nokia X6 */ + { NOKIA_PCSUITE_ACM_INFO(0x026c), }, /* Nokia N97 Mini */ + { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ + { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ + { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ + { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ + + /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ + + /* control interfaces without any protocol set */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, + USB_CDC_PROTO_NONE) }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, @@ -1533,7 +1618,6 @@ static struct usb_device_id acm_ids[] = { { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_ACM_PROTO_AT_CDMA) }, - /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */ { } }; diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index c4a0ee8ffccf..519eb638b6e9 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -112,7 +112,6 @@ struct acm { struct mutex mutex; struct usb_cdc_line_coding line; /* bits, stop, parity */ struct work_struct work; /* work queue entry for line discipline waking up */ - struct work_struct waker; wait_queue_head_t drain_wait; /* close processing */ struct tasklet_struct urb_task; /* rx processing */ spinlock_t throttle_lock; /* synchronize throtteling and read callback */ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 24120db005a2..582aa87c4b0d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -946,10 +946,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci; + struct usbdevfs_connectinfo ci = { + .devnum = ps->dev->devnum, + .slow = ps->dev->speed == USB_SPEED_LOW + }; - ci.devnum = ps->dev->devnum; - ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; return 0; @@ -1176,6 +1177,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, free_async(as); return -ENOMEM; } + /* Isochronous input data may end up being discontiguous + * if some of the packets are short. Clear the buffer so + * that the gaps don't leak kernel data to userspace. + */ + if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) + memset(as->urb->transfer_buffer, 0, + uurb->buffer_length); } as->urb->dev = ps->dev; as->urb->pipe = (uurb->type << 30) | @@ -1312,10 +1320,14 @@ static int processcompl(struct async *as, void __user * __user *arg) void __user *addr = as->userurb; unsigned int i; - if (as->userbuffer && urb->actual_length) - if (copy_to_user(as->userbuffer, urb->transfer_buffer, - urb->actual_length)) + if (as->userbuffer && urb->actual_length) { + if (urb->number_of_packets > 0) /* Isochronous */ + i = urb->transfer_buffer_length; + else /* Non-Isoc */ + i = urb->actual_length; + if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) goto err_out; + } if (put_user(as->status, &userurb->status)) goto err_out; if (put_user(urb->actual_length, &userurb->actual_length)) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 4f864472c5c4..d784a8b3a6bd 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -625,9 +625,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; - /* driver is often null here; dev_dbg() would oops */ - pr_debug("usb %s: uevent\n", dev_name(dev)); - if (is_usb_device(dev)) { usb_dev = to_usb_device(dev); } else if (is_usb_interface(dev)) { @@ -639,6 +636,7 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) } if (usb_dev->devnum < 0) { + /* driver is often null here; dev_dbg() would oops */ pr_debug("usb %s: already deleted?\n", dev_name(dev)); return -ENODEV; } @@ -1177,9 +1175,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) udev->state == USB_STATE_SUSPENDED) goto done; - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - if (msg.event & PM_EVENT_AUTO) { + udev->do_remote_wakeup = device_may_wakeup(&udev->dev); status = autosuspend_check(udev, 0); if (status < 0) goto done; @@ -1744,6 +1741,23 @@ int usb_external_resume_device(struct usb_device *udev, pm_message_t msg) return status; } +static void choose_wakeup(struct usb_device *udev, pm_message_t msg) +{ + /* Remote wakeup is needed only when we actually go to sleep. + * For things like FREEZE and QUIESCE, if the device is already + * autosuspended then its current wakeup setting is okay. + */ + if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) { + udev->do_remote_wakeup = 0; + return; + } + + /* Allow remote wakeup if it is enabled, even if no interface drivers + * actually want it. + */ + udev->do_remote_wakeup = device_may_wakeup(&udev->dev); +} + int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev; @@ -1763,6 +1777,7 @@ int usb_suspend(struct device *dev, pm_message_t msg) } udev->skip_sys_resume = 0; + choose_wakeup(udev, msg); return usb_external_suspend_device(udev, msg); } diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 222ee07ea680..8164ba53cab7 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -159,9 +159,9 @@ void usb_major_cleanup(void) int usb_register_dev(struct usb_interface *intf, struct usb_class_driver *class_driver) { - int retval = -EINVAL; + int retval; int minor_base = class_driver->minor_base; - int minor = 0; + int minor; char name[20]; char *temp; @@ -173,12 +173,17 @@ int usb_register_dev(struct usb_interface *intf, */ minor_base = 0; #endif - intf->minor = -1; - - dbg ("looking for a minor, starting at %d", minor_base); if (class_driver->fops == NULL) - goto exit; + return -EINVAL; + if (intf->minor >= 0) + return -EADDRINUSE; + + retval = init_usb_class(); + if (retval) + return retval; + + dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base); down_write(&minor_rwsem); for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { @@ -186,20 +191,12 @@ int usb_register_dev(struct usb_interface *intf, continue; usb_minors[minor] = class_driver->fops; - - retval = 0; + intf->minor = minor; break; } up_write(&minor_rwsem); - - if (retval) - goto exit; - - retval = init_usb_class(); - if (retval) - goto exit; - - intf->minor = minor; + if (intf->minor < 0) + return -EXFULL; /* create a usb class device for this usb interface */ snprintf(name, sizeof(name), class_driver->name, minor - minor_base); @@ -213,11 +210,11 @@ int usb_register_dev(struct usb_interface *intf, "%s", temp); if (IS_ERR(intf->usb_dev)) { down_write(&minor_rwsem); - usb_minors[intf->minor] = NULL; + usb_minors[minor] = NULL; + intf->minor = -1; up_write(&minor_rwsem); retval = PTR_ERR(intf->usb_dev); } -exit: return retval; } EXPORT_SYMBOL_GPL(usb_register_dev); diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 05e6d313961e..1a78cd135aba 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -120,7 +120,7 @@ int usb_choose_configuration(struct usb_device *udev) * than a vendor-specific driver. */ else if (udev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC && - (!desc || desc->bInterfaceClass != + (desc && desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC)) { best = c; break; diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 7b393ef73792..603e213f29b9 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -140,7 +140,7 @@ static const u8 usb3_rh_dev_descriptor[18] = { 0x09, /* __u8 bMaxPacketSize0; 2^9 = 512 Bytes */ 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ - 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ + 0x03, 0x00, /* __le16 idProduct; device 0x0003 */ KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ 0x03, /* __u8 iManufacturer; */ diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 79782a1c43f6..bcbe10476197 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -234,7 +234,7 @@ struct hc_driver { /* xHCI specific functions */ /* Called by usb_alloc_dev to alloc HC device structures */ int (*alloc_dev)(struct usb_hcd *, struct usb_device *); - /* Called by usb_release_dev to free HC device structures */ + /* Called by usb_disconnect to free HC device structures */ void (*free_dev)(struct usb_hcd *, struct usb_device *); /* Bandwidth computation functions */ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c old mode 100644 new mode 100755 index c6341922eac1..9478cf70509b --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -37,9 +38,6 @@ #endif #endif -// cmy@091222: ¼Ç¼Host¶Ë¿ÚËùÁ¬½ÓµÄÉ豸 -static struct usb_device *g_usb_device = 0; - struct usb_hub { struct device *intfdev; /* the "interface" device */ struct usb_device *hdev; @@ -1170,8 +1168,6 @@ static void hub_disconnect(struct usb_interface *intf) kref_put(&hub->kref, hub_release); } -struct usb_hub *g_root_hub20 = NULL; -struct usb_hub *g_root_hub11 = NULL; static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *desc; @@ -1222,13 +1218,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n"); return -ENOMEM; } - if(hdev->parent == NULL) - { - if(!g_root_hub20) - g_root_hub20 = hub; - else if(!g_root_hub11) - g_root_hub11 = hub; - } kref_init(&hub->kref); INIT_LIST_HEAD(&hub->event_list); hub->intfdev = &intf->dev; @@ -1518,6 +1507,15 @@ static inline void usb_stop_pm(struct usb_device *udev) #endif +static void hub_free_dev(struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + /* Root hubs aren't real devices, so don't free HCD resources */ + if (hcd->driver->free_dev && udev->parent) + hcd->driver->free_dev(hcd, udev); +} + /** * usb_disconnect - disconnect a device (usbcore-internal) * @pdev: pointer to device being disconnected @@ -1588,16 +1586,8 @@ void usb_disconnect(struct usb_device **pdev) usb_stop_pm(udev); - // cmy: ²»´¦ÀíhubÉ豸 - if(USB_CLASS_HUB != udev->descriptor.bDeviceClass) - { - if(udev == g_usb_device) - g_usb_device = 0; -#ifdef CONFIG_ANDROID_POWER - android_unlock_suspend(&hub_suspend_lock); -#endif - } + hub_free_dev(udev); put_device(&udev->dev); } @@ -1778,7 +1768,6 @@ int usb_new_device(struct usb_device *udev) if (udev->parent) usb_autoresume_device(udev->parent); - usb_detect_quirks(udev); err = usb_enumerate_device(udev); /* Read descriptors */ if (err < 0) goto fail; @@ -1801,14 +1790,6 @@ int usb_new_device(struct usb_device *udev) dev_err(&udev->dev, "can't device_add, error %d\n", err); goto fail; } - // cmy: ÔÚÆô¶¯Ê±×Ô¶¯»áÌí¼Ólm0µÄhubÉ豸£¬²»Ðè¼Ç¼£¬²»ÐèÉÏËø - if(USB_CLASS_HUB != udev->descriptor.bDeviceClass) - { - g_usb_device = udev; -#ifdef CONFIG_ANDROID_POWER - android_lock_suspend(&hub_suspend_lock); -#endif - } (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); return err; @@ -2839,13 +2820,16 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, else i = udev->descriptor.bMaxPacketSize0; if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { - if (udev->speed != USB_SPEED_FULL || + if (udev->speed == USB_SPEED_LOW || !(i == 8 || i == 16 || i == 32 || i == 64)) { - dev_err(&udev->dev, "ep0 maxpacket = %d\n", i); + dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); retval = -EMSGSIZE; goto fail; } - dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); + if (udev->speed == USB_SPEED_FULL) + dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); + else + dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i); udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); usb_ep0_reinit(udev); } @@ -3081,6 +3065,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (status < 0) goto loop; + usb_detect_quirks(udev); + if (udev->quirks & USB_QUIRK_DELAY_INIT) + msleep(1000); + /* consecutive bus-powered hubs aren't reliable; they can * violate the voltage drop budget. if the new child has * a "powered" LED, users should notice we didn't enable it @@ -3159,6 +3147,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, loop: usb_ep0_reinit(udev); release_address(udev); + hub_free_dev(udev); usb_put_dev(udev); if ((status == -ENOTCONN) || (status == -ENOTSUPP)) break; diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 97b40ce133f0..4a6366a42129 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -515,13 +515,13 @@ static int fs_create_by_name (const char *name, mode_t mode, *dentry = NULL; mutex_lock(&parent->d_inode->i_mutex); *dentry = lookup_one_len(name, parent, strlen(name)); - if (!IS_ERR(dentry)) { + if (!IS_ERR(*dentry)) { if ((mode & S_IFMT) == S_IFDIR) error = usbfs_mkdir (parent->d_inode, *dentry, mode); else error = usbfs_create (parent->d_inode, *dentry, mode); } else - error = PTR_ERR(dentry); + error = PTR_ERR(*dentry); mutex_unlock(&parent->d_inode->i_mutex); return error; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 980a8d27fa50..409cc94a1331 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1185,13 +1185,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; - 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, true); - usb_disable_endpoint(dev, i + USB_DIR_IN, true); - } - /* getting rid of interfaces will disconnect * any drivers bound to them (a key side effect) */ @@ -1221,6 +1214,13 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) if (dev->state == USB_STATE_CONFIGURED) usb_set_device_state(dev, USB_STATE_ADDRESS); } + + 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, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); + } } /** @@ -1792,6 +1792,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) intf->dev.groups = usb_interface_groups; intf->dev.dma_mask = dev->dev.dma_mask; INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); + intf->minor = -1; device_initialize(&intf->dev); mark_quiesced(intf); dev_set_name(&intf->dev, "%d-%s:%d.%d", diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index ab93918d9207..80b062b28ce5 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -38,9 +38,16 @@ static const struct usb_device_id usb_quirk_list[] = { /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech Harmony 700-series */ + { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Philips PSC805 audio device */ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Artisman Watchdog Dongle */ + { USB_DEVICE(0x04b4, 0x0526), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Roland SC-8820 */ { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, @@ -64,6 +71,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */ { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF }, + /* Broadcom BCM92035DGROM BT dongle */ + { USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Action Semiconductor flash disk */ { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255 }, diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 0885d4abdc62..da9a2b835670 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -137,6 +137,16 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor) } EXPORT_SYMBOL_GPL(usb_anchor_urb); +/* Callers must hold anchor->lock */ +static void __usb_unanchor_urb(struct urb *urb, struct usb_anchor *anchor) +{ + urb->anchor = NULL; + list_del(&urb->anchor_list); + usb_put_urb(urb); + if (list_empty(&anchor->urb_list)) + wake_up(&anchor->wait); +} + /** * usb_unanchor_urb - unanchors an URB * @urb: pointer to the urb to anchor @@ -156,17 +166,14 @@ void usb_unanchor_urb(struct urb *urb) return; spin_lock_irqsave(&anchor->lock, flags); - if (unlikely(anchor != urb->anchor)) { - /* we've lost the race to another thread */ - spin_unlock_irqrestore(&anchor->lock, flags); - return; - } - urb->anchor = NULL; - list_del(&urb->anchor_list); + /* + * At this point, we could be competing with another thread which + * has the same intention. To protect the urb from being unanchored + * twice, only the winner of the race gets the job. + */ + if (likely(anchor == urb->anchor)) + __usb_unanchor_urb(urb, anchor); spin_unlock_irqrestore(&anchor->lock, flags); - usb_put_urb(urb); - if (list_empty(&anchor->urb_list)) - wake_up(&anchor->wait); } EXPORT_SYMBOL_GPL(usb_unanchor_urb); @@ -725,20 +732,11 @@ EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs); void usb_unlink_anchored_urbs(struct usb_anchor *anchor) { struct urb *victim; - unsigned long flags; - spin_lock_irqsave(&anchor->lock, flags); - while (!list_empty(&anchor->urb_list)) { - victim = list_entry(anchor->urb_list.prev, struct urb, - anchor_list); - usb_get_urb(victim); - spin_unlock_irqrestore(&anchor->lock, flags); - /* this will unanchor the URB */ + while ((victim = usb_get_from_anchor(anchor)) != NULL) { usb_unlink_urb(victim); usb_put_urb(victim); - spin_lock_irqsave(&anchor->lock, flags); } - spin_unlock_irqrestore(&anchor->lock, flags); } EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs); @@ -775,12 +773,11 @@ struct urb *usb_get_from_anchor(struct usb_anchor *anchor) victim = list_entry(anchor->urb_list.next, struct urb, anchor_list); usb_get_urb(victim); - spin_unlock_irqrestore(&anchor->lock, flags); - usb_unanchor_urb(victim); + __usb_unanchor_urb(victim, anchor); } else { - spin_unlock_irqrestore(&anchor->lock, flags); victim = NULL; } + spin_unlock_irqrestore(&anchor->lock, flags); return victim; } @@ -802,12 +799,7 @@ void usb_scuttle_anchored_urbs(struct usb_anchor *anchor) while (!list_empty(&anchor->urb_list)) { victim = list_entry(anchor->urb_list.prev, struct urb, anchor_list); - usb_get_urb(victim); - spin_unlock_irqrestore(&anchor->lock, flags); - /* this may free the URB */ - usb_unanchor_urb(victim); - usb_put_urb(victim); - spin_lock_irqsave(&anchor->lock, flags); + __usb_unanchor_urb(victim, anchor); } spin_unlock_irqrestore(&anchor->lock, flags); } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 774a2a142599..152781441b71 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -191,9 +191,6 @@ static void usb_release_dev(struct device *dev) hcd = bus_to_hcd(udev->bus); usb_destroy_configuration(udev); - /* Root hubs aren't real devices, so don't free HCD resources */ - if (hcd->driver->free_dev && udev->parent) - hcd->driver->free_dev(hcd, udev); usb_put_hcd(hcd); kfree(udev->product); kfree(udev->manufacturer); diff --git a/drivers/usb/dwc_otg/Kconfig b/drivers/usb/dwc_otg/Kconfig index 6f70c019c3da..e5573885b786 100755 --- a/drivers/usb/dwc_otg/Kconfig +++ b/drivers/usb/dwc_otg/Kconfig @@ -1,55 +1,59 @@ -config RK2818_HOST11 - tristate "RockChip USB Host 1.1 support" +config USB11_HOST + tristate "RockChip USB 1.1 host controller" + depends on USB ---help--- - This driver supports Rockchip USB HOST 1.1 - controller in RK281X. + This driver supports Rockchip USB 1.1 HOST + controller. -config DWC_OTG - tristate "RockChip USB OTG 2.0 support" +config USB20_HOST + tristate "Rockchip USB 2.0 host controller" + depends on USB + ---help--- + This driver supports Rockchip USB2.0 host + controller. + +config USB20_OTG + tristate "RockChip USB 2.0 OTG controller" ---help--- - This driver supports Rockchip DWC_OTG - -config DWC_OTG_DEBUG - bool "enable debug mode" - depends on DWC_OTG - + This driver supports Rockchip USB2.0 DWC_OTG + controller. choice - tristate "DWC_OTG OPMODE" - default DWC_OTG_BOTH_HOST_SLAVE - depends on DWC_OTG + bool "USB2.0 OTG controller mode" + depends on USB20_OTG + default DWC_OTG_DEVICE_ONLY help RockChip DWC_OTG Controller can only work - one of following mode + in one of following mode config DWC_OTG_HOST_ONLY - bool "HOST ONLY MODE" - depends on DWC_OTG && USB + boolean "HOST ONLY MODE" + depends on USB20_OTG && USB + help + USB2.0 OTG controller worked in host mode + and device can support other gadgets. config DWC_OTG_DEVICE_ONLY - bool "DEVICE ONLY MODE" - depends on DWC_OTG && USB_GADGET + boolean "DEVICE ONLY MODE" + depends on USB20_OTG && USB_GADGET + help + USB2.0 OTG controller worked in device mode + and device can connect to PC via USB cable. -config DWC_OTG_BOTH_HOST_SLAVE - bool "BOTH HOST AND SLAVE" - depends on DWC_OTG && USB_GADGET && USB endchoice -choice - bool "USB controller mode" - depends on DWC_OTG - default DWC_OTG_NORMAL_PREFRENCE + +config DWC_CONN_EN + bool "connect to PC when vbus detect" + default y + depends on DWC_OTG_DEVICE_ONLY help - Rockchip dwc_otg controller + USB2.0 OTG controller always polling the USB vbus + + if selected, device will connect to PC automatic -config DWC_OTG_NORMAL_PREFERENCE - bool "NORMAL MODE" - depends on DWC_OTG_BOTH_HOST_SLAVE +config DWC_OTG_DEBUG + bool "DWC_OTG debug messages" + depends on USB11_HOST || USB20_HOST || USB20_OTG -config DWC_OTG_HOST_PREFERENCE - bool "HOST PREFERENCE MODE" - depends on DWC_OTG_HOST_ONLY || DWC_OTG_BOTH_HOST_SLAVE - -config DWC_OTG_DEVICE_PREFERENCE - bool "DEVICE PREFERENCE MODE" - depends on DWC_OTG_DEVICE_ONLY || DWC_OTG_BOTH_HOST_SLAVE - -endchoice +config DWC_OTG + tristate + default y if USB11_HOST || USB20_HOST || USB20_OTG diff --git a/drivers/usb/dwc_otg/Makefile b/drivers/usb/dwc_otg/Makefile index d119d99ad02d..9b5cd633712e 100755 --- a/drivers/usb/dwc_otg/Makefile +++ b/drivers/usb/dwc_otg/Makefile @@ -13,13 +13,10 @@ ifeq ($(CONFIG_DWC_OTG_HOST_ONLY),y) EXTRA_CFLAGS += -DDWC_HOST_ONLY endif -ifeq ($(CONFIG_DWC_OTG_DEVICE_ONLY),y) +ifneq ($(CONFIG_USB),y) EXTRA_CFLAGS += -DDWC_DEVICE_ONLY endif -ifeq ($(CONFIG_DWC_OTG_BOTH_HOST_SLAVE),y) -EXTRA_CFLAGS += -DDWC_BOTH_HOST_SLAVE -endif #EXTRA_CFLAGS += -Dlinux -DDWC_HS_ELECT_TST dwc_otg-objs := dwc_otg_driver.o dwc_otg_attr.o @@ -27,4 +24,4 @@ dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o dwc_otg-objs += dwc_otg_pcd.o dwc_otg_pcd_intr.o dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o -obj-$(CONFIG_DWC_OTG) := dwc_otg.o gadget_supplement.o +obj-$(CONFIG_DWC_OTG) := dwc_otg.o diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c index c710d037eb7e..9fb2024a5888 100755 --- a/drivers/usb/dwc_otg/dwc_otg_attr.c +++ b/drivers/usb/dwc_otg/dwc_otg_attr.c @@ -696,7 +696,7 @@ static ssize_t rd_reg_test_show( struct device *_dev, int start_jiffies; dwc_otg_device_t *otg_dev = _dev->platform_data; - printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", + DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", HZ, MSEC_PER_JIFFIE, loops_per_jiffy); start_jiffies = jiffies; for (i = 0; i < RW_REG_COUNT; i++) { @@ -722,7 +722,7 @@ static ssize_t wr_reg_test_show( struct device *_dev, dwc_otg_device_t *otg_dev = _dev->platform_data; uint32_t reg_val; - printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", + DWC_PRINT("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", HZ, MSEC_PER_JIFFIE, loops_per_jiffy); reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz); start_jiffies = jiffies; @@ -757,7 +757,7 @@ static ssize_t debug_store( struct device *_dev, return count; } -DEVICE_ATTR(step, S_IRUGO|S_IWUSR, debug_show, debug_store); +DEVICE_ATTR(debug, S_IRUGO|S_IWUSR, debug_show, debug_store); /**@}*/ /** @@ -794,7 +794,7 @@ void dwc_otg_attr_create (struct device *dev) error |= device_create_file(dev, &dev_attr_hcd_frrem); error |= device_create_file(dev, &dev_attr_rd_reg_test); error |= device_create_file(dev, &dev_attr_wr_reg_test); - error |= device_create_file(dev, &dev_attr_step); + error |= device_create_file(dev, &dev_attr_debug); if (error) pr_err("DWC_OTG: Creating some device files failed\n"); } @@ -832,5 +832,5 @@ void dwc_otg_attr_remove (struct device *dev) device_remove_file(dev, &dev_attr_hcd_frrem); device_remove_file(dev, &dev_attr_rd_reg_test); device_remove_file(dev, &dev_attr_wr_reg_test); - device_remove_file(dev, &dev_attr_step); + device_remove_file(dev, &dev_attr_debug); } diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index 089e1ae5687d..a5f2c07dda45 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -210,7 +210,7 @@ dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr, core_if->srp_timer_started = 0; core_if->usb_wakeup = 0; - if(dwc_core_if == NULL) +// if(dwc_core_if == NULL) dwc_core_if = core_if; return core_if; } @@ -243,7 +243,7 @@ void dwc_otg_cil_remove( dwc_otg_core_if_t *_core_if ) * * @param[in] _core_if Programming view of DWC_otg controller. */ -extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if ) +void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if ) { gahbcfg_data_t ahbcfg = { .d32 = 0}; ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ @@ -442,9 +442,7 @@ void dwc_otg_core_init(dwc_otg_core_if_t *_core_if) /* Common Initialization */ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); - //printk("%s:::::::::::::gusbcfg is %x\n",__func__,usbcfg.d32); regvalue = dwc_read_reg32(&global_regs->gintsts); - //printk("%s:::::::::::::gusbcfg is %x\n",__func__,regvalue); /* Program the ULPI External VBUS bit if needed */ usbcfg.b.ulpi_ext_vbus_drv = (_core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0; @@ -485,8 +483,6 @@ void dwc_otg_core_init(dwc_otg_core_if_t *_core_if) _core_if->nperio_tx_fifo_size = dwc_read_reg32( &global_regs->gnptxfsiz) >> 16; - //printk( "%s::Total FIFO SZ=%d, Rx FIFO SZ=%d,NP Tx FIFO SZ=%d\n",__func__, _core_if->total_fifo_size, - // _core_if->rx_fifo_size, _core_if->nperio_tx_fifo_size); DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", _core_if->total_fifo_size); DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", _core_if->rx_fifo_size); DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", _core_if->nperio_tx_fifo_size); @@ -1050,16 +1046,6 @@ void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc) } } } -#if 1 - //yk@rk 20100714 - if((_core_if->core_params->host_channels <= 2)&& - _hc->ep_is_in && - _hc->ep_type == DWC_OTG_EP_TYPE_BULK) - { - //DWC_PRINT("%s bulk in\n",__func__); - hc_intr_mask.b.nak = 1; - } -#endif } else { @@ -1236,7 +1222,11 @@ void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if, dwc_otg_hc_regs_t *hc_regs; dwc_otg_core_global_regs_t *global_regs; dwc_otg_host_global_regs_t *host_global_regs; - + if((!_core_if)||(!_hc)) + { + DWC_PRINT("%s parm error _core_if:0x%x, _hc:0x%x\n",__func__,(uint32_t)_core_if,(uint32_t)_hc); + return; + } hc_regs = _core_if->host_if->hc_regs[_hc->hc_num]; global_regs = _core_if->core_global_regs; host_global_regs = _core_if->host_if->host_global_regs; @@ -2999,22 +2989,6 @@ extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if, _cb->p = _p; } -void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if ) -{ - gotgctl_data_t gctrl; - dctl_data_t dctl = {.d32=0}; - - gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); - if( !gctrl.b.bsesvld ) - return ; - - printk("%s\n" , __func__); - /* soft disconnect */ - dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); - dctl.b.sftdiscon = 1; - dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); -} - /** * This functions reads the device registers and prints them * @@ -3279,40 +3253,87 @@ void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if) void dump_scu_regs(void) { int regvalue; - printk("_______________________System Regs________________________________\n"); + DWC_PRINT("_______________________System Regs________________________________\n"); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x00)); - printk("SCU_APLL_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_APLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x04)); - printk("SCU_DPLL_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_DPLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x08)); - printk("SCU_CPLL_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CPLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x0c)); - printk("SCU_MODE_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_PPLL_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x10)); - printk("SCU_PMU_MODE: 0x%08x\n",regvalue); + DWC_PRINT("CRU_MODE_CON: 0x%08x\n",regvalue); + + /////////////////////////////////////////////////////////////// regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x14)); - printk("SCU_CLKSEL0_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL0_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x18)); - printk("SCU_CLKSEL1_CON: 0x%08x\n",regvalue); - regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x1c)); - printk("SCU_CLKGATE0_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL1_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x1C)); + DWC_PRINT("CRU_CLKSEL2_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x20)); - printk("SCU_CLKGATE1_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL3_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x24)); - printk("SCU_CLKGATE2_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL4_CON: 0x%08x\n",regvalue); regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x28)); - printk("SCU_SOFTRST_CON: 0x%08x\n",regvalue); + DWC_PRINT("CRU_CLKSEL5_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x2C)); + DWC_PRINT("CRU_CLKSEL6_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x30)); + DWC_PRINT("CRU_CLKSEL7_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x34)); + DWC_PRINT("CRU_CLKSEL8_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x38)); + DWC_PRINT("CRU_CLKSEL9_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x3C)); + DWC_PRINT("CRU_CLKSEL10_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x40)); + DWC_PRINT("CRU_CLKSEL11_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x44)); + DWC_PRINT("CRU_CLKSEL12_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x48)); + DWC_PRINT("CRU_CLKSEL12_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x4C)); + DWC_PRINT("CRU_CLKSEL14_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x50)); + DWC_PRINT("CRU_CLKSEL15_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x54)); + DWC_PRINT("CRU_CLKSEL16_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x58)); + DWC_PRINT("CRU_CLKSEL17_CON: 0x%08x\n",regvalue); + + /////////////////////////////////////////////////////////////// + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x5c)); + DWC_PRINT("CRU_CLKGATE0_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x60)); + DWC_PRINT("CRU_CLKGATE1_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x64)); + DWC_PRINT("CRU_CLKGATE2_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x68)); + DWC_PRINT("CRU_CLKGATE3_CON: 0x%08x\n",regvalue); + + /////////////////////////////////////////////////////////////// + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x6C)); + DWC_PRINT("CRU_SOFTRST0_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x70)); + DWC_PRINT("CRU_SOFTRST1_CON: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(SCU_BASE_ADDR_VA+0x74)); + DWC_PRINT("CRU_SOFTRST2_CON: 0x%08x\n",regvalue); + + ///////////////////////////////////////////////////////////// regvalue = dwc_read_reg32((uint32_t *)(USB_GRF_CON)); - printk("USB_PHY_CON1: 0x%08x\n",regvalue); + DWC_PRINT("USB_PHY_CON1: 0x%08x\n",regvalue); + regvalue = dwc_read_reg32((uint32_t *)(USB_GRF_IOMUX)); + DWC_PRINT("GRF_GPIO4L_IOMUX: 0x%08x\n",regvalue); } void dwc_otg_dump_flags(dwc_otg_core_if_t *_core_if) { - printk("_______________________dwc_otg flags_______________________________\n"); - printk("core_if->op_state = %x\n",_core_if->op_state); - printk("core_if->usb_mode = %x\n",_core_if->usb_mode); - printk("core_if->usb_wakeup = %x\n",_core_if->usb_wakeup); + DWC_PRINT("_______________________dwc_otg flags_______________________________\n"); + DWC_PRINT("core_if->op_state = %x\n",_core_if->op_state); + DWC_PRINT("core_if->usb_mode = %x\n",_core_if->usb_mode); + DWC_PRINT("core_if->usb_wakeup = %x\n",_core_if->usb_wakeup); } -int dwc_step = 0; int dwc_debug(int flag) { dwc_otg_core_if_t *core_if = dwc_core_if; @@ -3342,7 +3363,6 @@ int dwc_debug(int flag) dwc_otg_dump_flags(core_if); break; case 8: - dwc_step = 0; break; case 9: dwc_otg_dump_flags(core_if); diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c index 783a48a1e323..a86169f1241f 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c @@ -193,7 +193,7 @@ int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *_core_if) dctl.d32 = dwc_read_reg32( &_core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 1; dwc_write_reg32( &_core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); - printk("********session end intr,soft disconnect************************\n"); + DWC_PRINT("********session end intr,soft disconnect************************\n"); } _core_if->otg_dev->pcd->vbus_status = 0; /////////////////////////////// @@ -337,93 +337,11 @@ int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *_core_if) * * @param _core_if Programming view of DWC_otg controller. */ -#ifdef DWC_BOTH_HOST_SLAVE -extern void dwc_otg_force_device(dwc_otg_core_if_t *core_if); -extern void dwc_otg_force_host(dwc_otg_core_if_t *core_if); -extern int rk28_usb_suspend( int exitsuspend ); -#endif int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if) { gintsts_data_t gintsts = { .d32 = 0 }; - #ifdef DWC_BOTH_HOST_SLAVE - uint32_t count = 0; - volatile gotgctl_data_t gctrl; - dwc_otg_pcd_t *pcd = _core_if->otg_dev->pcd; - gintmsk_data_t gintmsk = { .d32 = 0 }; - gotgctl_data_t gotgctl = { .d32 = 0 }; - if(pcd &&(pcd->phy_suspend == 1)) - { - rk28_usb_suspend( 1 ); - } - - /* - * yangkai@rk, 20100331 - * ³äµçÆ÷½ÓÈëʱÓпÉÄÜUSB IDΪµÍ, hostÉ豸Èç¹û¿ìËٰβ壬»áµ±³É³äµçÆ÷´¦Àí - */ - gctrl.d32 = dwc_read_reg32( &_core_if->core_global_regs->gotgctl ); - #if 0 - if( gctrl.b.bsesvld ) - { - if(pcd &&(pcd->vbus_status == 0)) - pcd->vbus_status = 1; - gintsts.b.conidstschng = 1; - dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32); - return 1; - } - #endif -// cmy: Ö»Óе±usb´¦ÓÚÕý³£Ä£Ê½Ê±£¬²Å´¦Àí¸ÃÖжϽøÐÐÇл» - if(_core_if->usb_mode != USB_MODE_NORMAL) - { - DWC_PRINT("_core_if->usb_mode=%d\n", _core_if->usb_mode); - gintsts.b.conidstschng = 1; - dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32); - return 1; - } - DWC_DEBUGPL(DBG_CIL, "switch\n"); - /* - * Need to disable SOF interrupt immediately. If switching from device - * to host, the PCD interrupt handler won't handle the interrupt if - * host mode is already set. The HCD interrupt handler won't get - * called if the HCD state is HALT. This means that the interrupt does - * not get handled and Linux complains loudly. - */ - gintmsk.b.sofintr = 1; - dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, gintmsk.d32, 0); - - DWC_DEBUGPL(DBG_CIL, " ++Connector ID Status Change Interrupt++ (%s)\n", - (dwc_otg_is_host_mode(_core_if)?"Host":"Device")); - gotgctl.d32 = dwc_read_reg32(&_core_if->core_global_regs->gotgctl); - DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32); - DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts); - - /* B-Device connector (Device Mode) */ - if (gotgctl.b.conidsts) { - /* Wait for switch to device mode. */ - while (!dwc_otg_is_device_mode(_core_if) ){ - DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n", - (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral")); - MDELAY(100); - if (++count > 10000) *(uint32_t*)NULL=0; - } - - hcd_stop(_core_if); - _core_if->op_state = B_PERIPHERAL; - pcd->phy_suspend = 1; - pcd->vbus_status = 0; - dwc_otg_pcd_start_vbus_timer( pcd ); - } else { - /* A-Device connector (Host Mode) */ - while (!dwc_otg_is_host_mode(_core_if) ) { - DWC_PRINT("Waiting for Host Mode, Mode=%s\n", - (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral")); - MDELAY(100); - if (++count > 10000) *(uint32_t*)NULL=0; - } - dwc_otg_force_host(_core_if); - } - #endif /* Set flag and clear interrupt */ gintsts.b.conidstschng = 1; dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32); @@ -450,27 +368,7 @@ int32_t dwc_otg_handle_session_req_intr( dwc_otg_core_if_t *_core_if ) DWC_PRINT("SRP: Device mode\n"); } else { DWC_PRINT("SRP: Host mode\n"); -/* - int regvalue; - printk("__________________________________________________________________\n"); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gotgint); - printk("gotgint is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gahbcfg); - printk("gahbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gusbcfg); - printk("gusbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->grstctl); - printk("grstctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gintsts); - printk("gintsts is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gintmsk); - printk("gintmsk is %08x\n",regvalue); - regvalue = dwc_read_reg32(&_core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - printk("__________________________________________________________________\n"); -*/ + // dump_coreif(_core_if); // dump_hostif(_core_if); dwc_otg_dump_global_registers(_core_if); @@ -578,8 +476,7 @@ int32_t dwc_otg_handle_disconnect_intr( dwc_otg_core_if_t *_core_if) op_state_str(_core_if)); /** @todo Consolidate this if statement. */ -#ifndef DWC_BOTH_HOST_SLAVE -#ifndef DWC_HOST_ONLY +#if 0//ndef DWC_HOST_ONLY if (_core_if->op_state == B_HOST) { /* If in device mode Disconnect and stop the HCD, then * start the PCD. */ @@ -609,7 +506,6 @@ int32_t dwc_otg_handle_disconnect_intr( dwc_otg_core_if_t *_core_if) hcd_disconnect( _core_if ); } } -#endif #endif gintsts.d32 = 0; gintsts.b.disconnect = 1; @@ -632,7 +528,7 @@ int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *_core_if ) gintsts_data_t gintsts; DWC_DEBUGPL(DBG_ANY,"USB SUSPEND\n"); - printk("USB SUSPEND\n"); + DWC_PRINT("USB SUSPEND\n"); if (dwc_otg_is_device_mode( _core_if ) ) { /* Check the Device status register to determine if the Suspend @@ -648,7 +544,7 @@ int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *_core_if ) /** @todo Add a module parameter for power management. */ if (dsts.b.suspsts && _core_if->hwcfg4.b.power_optimiz) { - printk("suspend power_optimiz\n"); + DWC_PRINT("suspend power_optimiz\n"); #if 0 pcgcctl_data_t power = {.d32=0}; DWC_DEBUGPL(DBG_CIL, "suspend\n"); diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index 735d7fa57c75..6b6361d59673 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -69,10 +69,12 @@ #include "dwc_otg_hcd.h" //#define DWC_DRIVER_VERSION "2.60a 22-NOV-2006" -#define DWC_DRIVER_VERSION "2.70 2009-12-31" +//#define DWC_DRIVER_VERSION "2.70 2009-12-31" +#define DWC_DRIVER_VERSION "3.00 2010-12-12 rockchip" + #define DWC_DRIVER_DESC "HS OTG USB Controller driver" -static const char dwc_driver_name[] = "dwc_otg"; +static const char dwc_driver_name[] = "usb20_otg"; dwc_otg_device_t* g_otgdev = NULL; @@ -148,11 +150,11 @@ static dwc_otg_core_params_t dwc_otg_module_params = { .rx_thr_length = -1, }; -#ifdef CONFIG_RK2818_HOST11 +#ifdef CONFIG_USB11_HOST dwc_otg_device_t* g_host11 = NULL; -static dwc_otg_core_params_t rk28_host11_module_params = { +static dwc_otg_core_params_t host11_module_params = { .opt = -1, .otg_cap = -1, .dma_enable = -1, @@ -221,6 +223,80 @@ static dwc_otg_core_params_t rk28_host11_module_params = { .rx_thr_length = -1, }; #endif + +#ifdef CONFIG_USB20_HOST +dwc_otg_device_t* g_host20 = NULL; + +static dwc_otg_core_params_t host20_module_params = { + .opt = -1, + .otg_cap = -1, + .dma_enable = -1, + .dma_burst_size = -1, + .speed = -1, + .host_support_fs_ls_low_power = -1, + .host_ls_low_power_phy_clk = -1, + .enable_dynamic_fifo = -1, + .data_fifo_size = -1, + .dev_rx_fifo_size = -1, + .dev_nperio_tx_fifo_size = -1, + .dev_perio_tx_fifo_size = + { /* dev_perio_tx_fifo_size_1 */ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, /* 15 */ + .host_rx_fifo_size = -1, + .host_nperio_tx_fifo_size = -1, + //.host_perio_tx_fifo_size = 512, + .host_perio_tx_fifo_size = -1, + .max_transfer_size = -1, + .max_packet_count = -1, + .host_channels = -1, + .dev_endpoints = -1, + .phy_type = -1, + .phy_utmi_width = -1, + .phy_ulpi_ddr = -1, + .phy_ulpi_ext_vbus = -1, + .i2c_enable = -1, + .ulpi_fs_ls = -1, + .ts_dline = -1, + .en_multiple_tx_fifo = -1, + .dev_tx_fifo_size = + { /* dev_tx_fifo_size */ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, /* 15 */ + .thr_ctl = -1, + .tx_thr_length = -1, + .rx_thr_length = -1, +}; +#endif + /** * This function shows the Driver Version. */ @@ -254,274 +330,35 @@ static ssize_t dbg_level_store(struct device_driver *_drv, const char *_buf, } static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store); -extern struct usb_hub *g_root_hub20; -extern struct usb_hub *g_root_hub11; -#ifdef DWC_BOTH_HOST_SLAVE -extern void hcd_start( dwc_otg_core_if_t *_core_if ); - -extern int rk28_usb_suspend( int exitsuspend ); -extern void hub_disconnect_device(struct usb_hub *hub); -extern void rk28_usb_force_disconnect( dwc_otg_core_if_t *core_if ); - -static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf) +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY +static ssize_t dwc_otg_conn_en_show(struct device_driver *_drv, char *_buf) { dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_core_if_t *core_if = otg_dev->core_if; -#if 1 - return sprintf (_buf, "%d\n", core_if->usb_mode); -#else - dwc_otg_device_t *otg_dev = lm_get_drvdata(g_lmdev); - dwc_otg_core_if_t *core_if = otg_dev->core_if; - gotgctl_data_t gctrl; - gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); - printk("OTGCTL=0x%08X\n", gctrl.d32); - - if(g_usb_mode == USB_NORMAL_MODE) - return sprintf (_buf, "Current usb mode: Normal Mode\n"); - else if(g_usb_mode == FORCE_HOST_MODE) - return sprintf (_buf, "Current usb mode: Force Host\n"); - else if(g_usb_mode == FORCE_DEVICE_MODE) - return sprintf (_buf, "Current usb mode: Force Device\n"); - else - return sprintf (_buf, "Current usb mode: Unknown\n"); -#endif + dwc_otg_pcd_t *_pcd = otg_dev->pcd; + return sprintf (_buf, "%d\n", _pcd->conn_en); } -void dwc_otg_force_host(dwc_otg_core_if_t *core_if) +static ssize_t dwc_otg_conn_en_store(struct device_driver *_drv, const char *_buf, + size_t _count) { + int enable = simple_strtoul(_buf, NULL, 10); dwc_otg_device_t *otg_dev = g_otgdev; - if(core_if->op_state == A_HOST) - { - printk("dwc_otg_force_host,already in A_HOST mode,everest\n"); - return; - } - if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1)) - { - rk28_usb_suspend( 1 ); - } - del_timer(&otg_dev->pcd->check_vbus_timer); - rk28_usb_force_disconnect(core_if); - if (core_if->pcd_cb && core_if->pcd_cb->stop ) { - core_if->pcd_cb->stop( core_if->pcd_cb->p ); - } - - //core_if->op_state = A_HOST; - /* - * Initialize the Core for Host mode. - */ - dwc_otg_core_init(core_if); - dwc_otg_enable_global_interrupts(core_if); - hcd_start( core_if ); + dwc_otg_pcd_t *_pcd = otg_dev->pcd; + DWC_PRINT("%s %d->%d\n",__func__, _pcd->conn_en, enable); + _pcd->conn_en = enable; + return _count; } -void dwc_otg_force_device(dwc_otg_core_if_t *core_if) +static DRIVER_ATTR(dwc_otg_conn_en, S_IRUGO|S_IWUSR, dwc_otg_conn_en_show, dwc_otg_conn_en_store); +static ssize_t vbus_status_show(struct device_driver *_drv, char *_buf) { dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_disable_global_interrupts( core_if ); - hub_disconnect_device(g_root_hub20); - if (core_if->hcd_cb && core_if->hcd_cb->stop) { - core_if->hcd_cb->stop( core_if->hcd_cb->p ); - } - if(core_if->op_state == B_PERIPHERAL) - { - printk("dwc_otg_force_device,already in B_PERIPHERAL,everest\n"); - return; - } - otg_dev->core_if->op_state = B_PERIPHERAL; - /* Reset the Controller */ - dwc_otg_core_reset( core_if ); - otg_dev->pcd->phy_suspend = 1; - otg_dev->pcd->vbus_status = 0; - dwc_otg_pcd_start_vbus_timer( otg_dev->pcd ); - + dwc_otg_pcd_t *_pcd = otg_dev->pcd; + return sprintf (_buf, "%d\n", _pcd->vbus_status); } -static void dwc_otg_set_gusbcfg(dwc_otg_core_if_t *core_if, int mode) -{ - gusbcfg_data_t usbcfg = { .d32 = 0 }; - - usbcfg.d32 = dwc_read_reg32( &core_if->core_global_regs->gusbcfg); - switch(mode) - { - case USB_MODE_FORCE_HOST: - usbcfg.b.force_hst_mode = 1; - usbcfg.b.force_dev_mode = 0; - break; - case USB_MODE_FORCE_DEVICE: - usbcfg.b.force_hst_mode = 0; - usbcfg.b.force_dev_mode = 1; - break; - case USB_MODE_NORMAL: - usbcfg.b.force_hst_mode = 0; - usbcfg.b.force_dev_mode = 0; - break; - } - dwc_write_reg32( &core_if->core_global_regs->gusbcfg, usbcfg.d32 ); -} - -static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf, - size_t _count ) -{ - int new_mode = simple_strtoul(_buf, NULL, 16); - dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_core_if_t *core_if = otg_dev->core_if; - DWC_PRINT("%s %d->%d\n",__func__, core_if->usb_mode, new_mode); - if(core_if->usb_mode == new_mode) - { - return _count; - } - - switch(new_mode) - { - case USB_MODE_FORCE_HOST: - if(USB_MODE_FORCE_DEVICE == core_if->usb_mode) - {/* device-->host */ - core_if->usb_mode = new_mode; - dwc_otg_force_host(core_if); - } - else if(USB_MODE_NORMAL == core_if->usb_mode) - { - core_if->usb_mode = new_mode; - if(dwc_otg_is_host_mode(core_if)) - { - dwc_otg_set_gusbcfg(core_if, new_mode); - } - else - { - dwc_otg_force_host(core_if); - } - } - break; - case USB_MODE_FORCE_DEVICE: - if(USB_MODE_FORCE_HOST == core_if->usb_mode) - { - core_if->usb_mode = new_mode; - dwc_otg_force_device(core_if); - } - else if(USB_MODE_NORMAL == core_if->usb_mode) - { - core_if->usb_mode = new_mode; - if(dwc_otg_is_device_mode(core_if)) - { - dwc_otg_set_gusbcfg(core_if, new_mode); - } - else - { - dwc_otg_force_device(core_if); - } - } - break; - case USB_MODE_NORMAL: - #if 1 - if(USB_MODE_FORCE_DEVICE == core_if->usb_mode) - { - core_if->usb_mode = new_mode; - if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1)) - { - rk28_usb_suspend( 1 ); - } - del_timer(&otg_dev->pcd->check_vbus_timer); - dwc_otg_set_gusbcfg(core_if, new_mode); - msleep(50); - if(dwc_otg_is_host_mode(core_if)) - { - dwc_otg_force_host(core_if); - } - else - { - dwc_otg_pcd_start_vbus_timer( otg_dev->pcd ); - } - //mdelay(10); - //core_if->usb_mode = new_mode; - //if(!dwc_otg_connid(core_if)) - // dwc_otg_force_host(core_if); - } - else if(USB_MODE_FORCE_HOST == core_if->usb_mode) - { - if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1)) - { - rk28_usb_suspend( 1 ); - } - core_if->usb_mode = new_mode; - dwc_otg_set_gusbcfg(core_if, new_mode); - msleep(40); - if(dwc_otg_is_device_mode(core_if)) - { - dwc_otg_force_device(core_if); - } - //if(dwc_otg_connid(core_if)) - // hub_disconnect_device(); - //core_if->usb_mode = new_mode; - // dwc_otg_force_device(core_if); - } - #endif - break; - default: - break; - } - return _count; -} -int otg_debug( int action ) -{ - dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_core_if_t *core_if = otg_dev->core_if; - switch(action) - { - case 0: - dwc_otg_set_gusbcfg(core_if, USB_MODE_FORCE_HOST); - break; - case 1: - dwc_otg_set_gusbcfg(core_if, USB_MODE_FORCE_DEVICE); - break; - case 2: - dwc_otg_set_gusbcfg(core_if, USB_MODE_NORMAL); - break; - default: - break; - } - return 0; -} - -static DRIVER_ATTR(force_usb_mode, 0666/*S_IRUGO|S_IWUSR*/, force_usb_mode_show, force_usb_mode_store); +static DRIVER_ATTR(vbus_status, S_IRUGO|S_IWUSR, vbus_status_show, NULL); #endif -int rk28_usb_check_connectid_change(void) -{ -#ifdef DWC_BOTH_HOST_SLAVE - dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_core_if_t *core_if = otg_dev->core_if; - gintsts_data_t gintsts; - - __udelay(1000);//40ms - - gintsts.d32 = dwc_read_reg32(&core_if->core_global_regs->gintsts); - if(gintsts.b.conidstschng) - { - //debug_print("rk28 connect id change %d \n",change); - core_if->usb_wakeup = 1; - return 1; - } -#endif - return 0; -} - -int rk28_usb_check_vbus_change( void ) -{ -#ifndef DWC_HOST_ONLY - dwc_otg_device_t *otg_dev = g_otgdev; - dwc_otg_core_if_t *core_if = otg_dev->core_if; - gotgctl_data_t gctrl; - gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl); - if(gctrl.b.bsesvld != otg_dev->pcd->vbus_status) - { - /* 20091104,HSL@RK,plug and unplg quickly, timer will not know,so let timer connect again */ - otg_dev->pcd->vbus_status = 0; - core_if->usb_wakeup = 1; - return 1; - } -#endif - return 0; -} - /** * This function is called during module intialization to verify that * the module parameters are in a valid state. @@ -772,11 +609,10 @@ static int check_parameters(dwc_otg_core_if_t *core_if) (core_params->max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))), ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1)); -// yk@rk use 1 channel in host 1.1 retval += DWC_OTG_PARAM_CHECK_VALID(host_channels, "host_channels", (core_params->host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)), - (core_if->hwcfg2.b.num_host_chan));// + 1 + (core_if->hwcfg2.b.num_host_chan + 1)); retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints, "dev_endpoints", @@ -958,14 +794,14 @@ static int dwc_otg_driver_remove(struct platform_device *pdev) free_irq( platform_get_irq(to_platform_device(dev),0), otg_dev ); } -#ifndef DWC_DEVICE_ONLY +#ifdef CONFIG_DWC_OTG_HOST_ONLY if (otg_dev->hcd != NULL) { dwc_otg_hcd_remove(dev); } #endif -#ifndef DWC_HOST_ONLY +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY if (otg_dev->pcd != NULL) { dwc_otg_pcd_remove(dev); @@ -1023,24 +859,31 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) dwc_otg_device_t *dwc_otg_device; int32_t snpsid; int irq; + int32_t regval; /* *Enable usb phy */ unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - *otg_phy_con1 |= (0x01<<2); - *otg_phy_con1 |= (0x01<<3); // exit suspend. - *otg_phy_con1 &= ~(0x01<<2); -#ifndef CONFIG_RK2818_HOST11 - *otg_phy_con1 |= (0x01<<31); + regval = * otg_phy_con1; + regval |= (0x01<<2); + regval |= (0x01<<3); // exit suspend. + regval &= ~(0x01<<2); +#ifndef CONFIG_USB11_HOST + regval |= (0x01<<28); #endif +#ifndef CONFIG_USB20_HOST + regval &= ~(0x01<<14); // exit suspend. + regval |= (0x01<<13); // software control +#endif + *otg_phy_con1 = regval; #if 0 otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); - printk("otgreg 0x%x",otgreg); + DWC_PRINT("otgreg 0x%x",otgreg); dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); #endif - printk("dwc_otg_driver_probe,everest\n"); + DWC_PRINT("dwc_otg_driver_probe,everest\n"); dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); @@ -1069,7 +912,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) retval = -ENOMEM; goto fail; } - printk("%s otg2.0 reg addr: 0x%x remap:0x%x\n",__func__, + DWC_PRINT("%s otg2.0 reg addr: 0x%x remap:0x%x\n",__func__, (unsigned)res_base->start, (unsigned)dwc_otg_device->base); #if 0 dwc_otg_device->base = (void*)(USB_OTG_BASE_ADDR_VA); @@ -1090,7 +933,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40)); if ((snpsid & 0xFFFFF000) != 0x4F542000) { - printk("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 0x4F542000 ); + DWC_PRINT("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 0x4F542000 ); dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid); retval = -EINVAL; goto fail; @@ -1156,14 +999,10 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) set_irq_type(irq, IRQT_LOW); #endif -#ifdef CONFIG_DWC_OTG_HOST_PREFERENCE - dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST; -#else -#ifdef CONFIG_DWC_OTG_DEVICE_PREFERENCE +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_DEVICE; #else - dwc_otg_device->core_if->usb_mode = USB_MODE_NORMAL; -#endif + dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST; #endif /* @@ -1173,7 +1012,8 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) /* Initialize the bus state. If the core is in Device Mode * HALT the USB bus and return. */ -#ifndef DWC_DEVICE_ONLY +#ifdef CONFIG_DWC_OTG_HOST_ONLY + USB_IOMUX_INIT(GPIO4A5_OTG0DRVVBUS_NAME, GPIO4L_OTG0_DRV_VBUS); /* * Initialize the HCD */ @@ -1185,7 +1025,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) goto fail; } #endif -#ifndef DWC_HOST_ONLY +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY /* * Initialize the PCD */ @@ -1197,17 +1037,19 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) goto fail; } #endif + + /* * Enable the global interrupt after all the interrupt * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); - printk("dwc_otg_driver_probe end, everest\n"); + DWC_PRINT("dwc_otg_driver_probe end, everest\n"); return 0; fail: devm_kfree(&pdev->dev, dwc_otg_device); - printk("dwc_otg_driver_probe fail,everest\n"); + DWC_PRINT("dwc_otg_driver_probe fail,everest\n"); return retval; } @@ -1218,14 +1060,9 @@ static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t st dwc_otg_core_if_t *core_if = otg_dev->core_if; if(core_if->op_state == A_HOST) { - printk("%s,A_HOST mode\n", __func__); + DWC_PRINT("%s,A_HOST mode\n", __func__); return 0; } - //gotgctl_data_t gctrl; -#if 0 - if( __rkusb_debug_mod() ) - return 0; -#endif /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); dwc_otg_disable_global_interrupts(core_if); @@ -1243,13 +1080,10 @@ static int dwc_otg_driver_resume(struct platform_device *_dev ) core_if->core_global_regs; if(core_if->op_state == A_HOST) { - printk("%s,A_HOST mode\n", __func__); + DWC_PRINT("%s,A_HOST mode\n", __func__); return 0; } -#if 0 - if( __rkusb_debug_mod() ) - goto sendwakeup; -#endif + /* soft disconnect */ /* 20100226,HSL@RK,if not disconnect,when usb cable in,will auto reconnect * besause now USB PHY is enable,and get USB RESET irq. @@ -1278,7 +1112,7 @@ static void dwc_otg_driver_shutdown(struct platform_device *_dev ) dwc_otg_core_if_t *core_if = otg_dev->core_if; dctl_data_t dctl = {.d32=0}; - printk("%s:: disconnect USB\n" , __func__ ); + DWC_PRINT("%s:: disconnect USB\n" , __func__ ); /* soft disconnect */ dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 1; @@ -1287,8 +1121,6 @@ static void dwc_otg_driver_shutdown(struct platform_device *_dev ) /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); - /* suspend phy. */ - //rk28_usb_suspend(0); } /** @@ -1313,118 +1145,11 @@ static struct platform_driver dwc_otg_driver = { .owner = THIS_MODULE}, }; -#ifdef CONFIG_RK2818_HOST11 +#ifdef CONFIG_USB11_HOST +extern void dwc_otg_hcd_remove(struct device *dev); +extern int __devinit host11_hcd_init(struct device *dev); -void rk28_host11_driver_enable(dwc_otg_core_if_t *core_if) -{ - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - unsigned int * scu_clkgate1_con = (unsigned int*)(USB_CLKGATE_CON); - /* - * enable usb phy & clockgate host controller - */ - core_if->usb_mode == USB_MODE_FORCE_HOST; - core_if->op_state = A_HOST; - dwc_modify_reg32(scu_clkgate1_con,0x80000000,0); //clock gate enable - udelay(10); - dwc_modify_reg32(otg_phy_con1,0x80000000,0);// exit suspend. - mdelay(10); - - /* - * Initialize the Core for Host mode. - */ - dwc_otg_core_init(core_if); - dwc_otg_enable_global_interrupts(core_if); - hcd_start( core_if ); -} - -void rk28_host11_driver_disable(dwc_otg_core_if_t *core_if) -{ - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - unsigned int * scu_clkgate1_con = (unsigned int*)(USB_CLKGATE_CON); - dwc_otg_disable_global_interrupts( core_if ); - hub_disconnect_device(g_root_hub11); - if (core_if->hcd_cb && core_if->hcd_cb->stop) { - core_if->hcd_cb->stop( core_if->hcd_cb->p ); - } - /* - *disable usb phy & clockgate host controller - */ - dwc_modify_reg32(otg_phy_con1,0x80000000,0x80000000);// exit suspend. - mdelay(10); - dwc_modify_reg32(scu_clkgate1_con,0x80000000,0x80000000); //clock gate enable -} -extern void dwc_otg_hcd_remove(struct device *_dev); -extern int __devinit rk28_host11_hcd_init(struct device *_dev); - -static int s_host11_enable = 0; - -static ssize_t enable_usb11_show(struct device_driver *_drv, char *_buf) -{ - return sprintf(_buf, "%d\n", s_host11_enable); -} - -static ssize_t enable_usb11_store(struct device_driver *_drv, const char *_buf, - size_t _count ) -{ - int enabled = simple_strtoul(_buf, NULL, 16); - dwc_otg_device_t *otg_dev = g_host11; - dwc_otg_core_if_t *core_if = otg_dev->core_if; - printk("enable usb11: %d\n", enabled); - - if(enabled) - {// enable usb1.1 - printk("BEGIN enable\n"); - if(s_host11_enable){ - printk("HOST1.1 already enable\n"); - return _count; - } - rk28_host11_driver_enable(core_if); -#if 0 - GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW); - msleep(10); - - GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_HIGH); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_HIGH); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_HIGH); -#endif - s_host11_enable = 1; - printk("END\n"); - } - else - {// disable usb1.1 -// cmy: - printk("BEGIN disable\n"); - rk28_host11_driver_disable(core_if); -#if 0 - GPIOSetPinDirection(GPIOPortB_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortB_Pin0, GPIO_LOW); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin0, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin0, GPIO_LOW); - msleep(10); - - GPIOSetPinDirection(GPIOPortG_Pin1, GPIO_OUT); - GPIOSetPinLevel(GPIOPortG_Pin1, GPIO_LOW); -#endif - s_host11_enable = 0; - printk("END\n"); - } - - return _count; -} - -static DRIVER_ATTR(enable_usb11, 0666/*S_IRUGO|S_IWUSR*/, enable_usb11_show, enable_usb11_store); - -static int rk28_host11_driver_remove(struct platform_device *pdev) +static int host11_driver_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; dwc_otg_device_t *otg_dev = dev->platform_data; @@ -1487,7 +1212,7 @@ static int rk28_host11_driver_remove(struct platform_device *pdev) * * @param[in] pdev platform_device definition */ -static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) +static __devinit int host11_driver_probe(struct platform_device *pdev) { struct resource *res_base; int retval = 0; @@ -1495,22 +1220,20 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) dwc_otg_device_t *dwc_otg_device; int32_t snpsid; int irq; - uint32_t otgreg; /* *Enable usb phy */ unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - *otg_phy_con1 &= ~(0x01<<31); // exit suspend. + *otg_phy_con1 &= ~(0x01<<28); // exit suspend. #if 0 *otg_phy_con1 |= (0x01<<2); *otg_phy_con1 |= (0x01<<3); // exit suspend. *otg_phy_con1 &= ~(0x01<<2); otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); - printk("%s otg2.0 reg addr: 0x%x",__func__,otgreg); + DWC_PRINT("%s otg2.0 reg addr: 0x%x",__func__,otgreg); dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); #endif - printk("%s otg_phy_con1:0x%x,everest\n",__func__,dwc_read_reg32(otg_phy_con1)); dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); @@ -1533,7 +1256,7 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) dwc_otg_device->base = ioremap(res_base->start,USBOTG_SIZE); - printk("%s host1.1 reg addr: 0x%x remap:0x%x\n",__func__, + DWC_PRINT("%s host1.1 reg addr: 0x%x remap:0x%x\n",__func__, (unsigned)res_base->start, (unsigned)dwc_otg_device->base); if (dwc_otg_device->base == NULL) { @@ -1550,7 +1273,7 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40)); if ((snpsid & 0xFFFFF000) != 0x4F542000) { - printk("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 0x4F542000 ); + DWC_PRINT("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 0x4F542000 ); dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid); retval = -EINVAL; goto fail; @@ -1565,15 +1288,14 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) g_host11 = dwc_otg_device; dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, - &rk28_host11_module_params); + &host11_module_params); if (dwc_otg_device->core_if == 0) { dev_err(dev, "CIL initialization failed!\n"); retval = -ENOMEM; goto fail; } - DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", - irq); + dwc_otg_device->core_if->otg_dev = dwc_otg_device; /* * Validate parameter values. @@ -1587,7 +1309,7 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) /* * Create Device Attributes in sysfs */ - //dwc_otg_attr_create(dev); + dwc_otg_attr_create(dev); /* * Disable the global interrupt until all the interrupt @@ -1622,10 +1344,10 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) /* * Initialize the HCD */ - retval = rk28_host11_hcd_init(dev); + retval = host11_hcd_init(dev); if (retval != 0) { - DWC_ERROR("rk28_host11_hcd_init failed\n"); + DWC_ERROR("host11_hcd_init failed\n"); dwc_otg_device->hcd = NULL; goto fail; } @@ -1634,16 +1356,16 @@ static __devinit int rk28_host11_driver_probe(struct platform_device *pdev) * handlers are installed. */ dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); - printk("rk28_host11_driver_probe end, everest\n"); + DWC_PRINT("host11_driver_probe end, everest\n"); return 0; fail: devm_kfree(&pdev->dev, dwc_otg_device); - printk("rk28_host11_driver_probe fail,everest\n"); + DWC_PRINT("host11_driver_probe fail,everest\n"); return retval; } -static int rk28_host11_driver_suspend(struct platform_device *_dev , pm_message_t state ) +static int host11_driver_suspend(struct platform_device *_dev , pm_message_t state ) { //struct device *dev = &_dev->dev; //dwc_otg_device_t *otg_dev = dev->platform_data; @@ -1651,7 +1373,7 @@ static int rk28_host11_driver_suspend(struct platform_device *_dev , pm_message_ return 0; } -static int rk28_host11_driver_resume(struct platform_device *_dev ) +static int host11_driver_resume(struct platform_device *_dev ) { //struct device *dev = &_dev->dev; //dwc_otg_device_t *otg_dev = dev->platform_data; @@ -1659,16 +1381,271 @@ static int rk28_host11_driver_resume(struct platform_device *_dev ) return 0; } -static struct platform_driver rk28_host11_driver = { - .probe = rk28_host11_driver_probe, - .remove = rk28_host11_driver_remove, - .suspend = rk28_host11_driver_suspend, - .resume = rk28_host11_driver_resume, +static struct platform_driver host11_driver = { + .probe = host11_driver_probe, + .remove = host11_driver_remove, + .suspend = host11_driver_suspend, + .resume = host11_driver_resume, .driver = { - .name = "rk2818_host11", + .name = "usb11_host", .owner = THIS_MODULE}, }; #endif + +#ifdef CONFIG_USB20_HOST +extern void dwc_otg_hcd_remove(struct device *dev); +extern int __devinit host20_hcd_init(struct device *_dev); + + +static int host20_driver_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + dwc_otg_device_t *otg_dev = dev->platform_data; + DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, pdev); + + if (otg_dev == NULL) + { + /* Memory allocation for the dwc_otg_device failed. */ + return 0; + } + + /* + * Free the IRQ + */ + if (otg_dev->common_irq_installed) + { + free_irq( platform_get_irq(to_platform_device(dev),0), otg_dev ); + } + + if (otg_dev->hcd != NULL) + { + dwc_otg_hcd_remove(dev); + } + + if (otg_dev->core_if != NULL) + { + dwc_otg_cil_remove( otg_dev->core_if ); + } + + /* + * Remove the device attributes + */ + //dwc_otg_attr_remove(dev); + + /* + * Return the memory. + */ + if (otg_dev->base != NULL) + { + iounmap(otg_dev->base); + } + kfree(otg_dev); + + /* + * Clear the drvdata pointer. + */ + dev->platform_data = 0; + + return 0; +} + +/** + * This function is called when an lm_device is bound to a + * dwc_otg_driver. It creates the driver components required to + * control the device (CIL, HCD, and PCD) and it initializes the + * device. The driver components are stored in a dwc_otg_device + * structure. A reference to the dwc_otg_device is saved in the + * lm_device. This allows the driver to access the dwc_otg_device + * structure on subsequent calls to driver methods for this device. + * + * @param[in] pdev platform_device definition + */ +static __devinit int host20_driver_probe(struct platform_device *pdev) +{ + struct resource *res_base; + int retval = 0; + struct device *dev = &pdev->dev; + dwc_otg_device_t *dwc_otg_device; + int32_t snpsid; + int irq; + uint32_t otgreg; + /* + *Enable usb phy + */ + unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); + otgreg = * otg_phy_con1; + otgreg |= (0x01<<13); // software control + otgreg |= (0x01<<14); // exit suspend. + otgreg &= ~(0x01<<13); // software control + *otg_phy_con1 = otgreg; + #if 0 + *otg_phy_con1 |= (0x01<<2); + *otg_phy_con1 |= (0x01<<3); // exit suspend. + *otg_phy_con1 &= ~(0x01<<2); + otgreg = ioremap(RK2818_USBOTG_PHYS,RK2818_USBOTG_SIZE); + DWC_PRINT("%s otg2.0 reg addr: 0x%x",__func__,otgreg); + dwc_modify_reg32((uint32_t *)(otgreg+0xc),0x20000000,0x20000000); + dwc_write_reg32((uint32_t *)(otgreg+0x440), 0x1000); + #endif + + dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); + + if (dwc_otg_device == 0) + { + dev_err(dev, "kmalloc of dwc_otg_device failed\n"); + retval = -ENOMEM; + goto fail; + } + + memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); + dwc_otg_device->reg_offset = 0xFFFFFFFF; + /* + * Map the DWC_otg Core memory into virtual address space. + */ + + res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_base) + goto fail; + + dwc_otg_device->base = + ioremap(res_base->start,USBOTG_SIZE); + DWC_PRINT("%s host2.0 reg addr: 0x%x remap:0x%x\n",__func__, + (unsigned)res_base->start, (unsigned)dwc_otg_device->base); + if (dwc_otg_device->base == NULL) + { + DWC_ERROR("ioremap() failed\n"); + retval = -ENOMEM; + goto fail; + } + DWC_DEBUGPL( DBG_CIL, "base addr for rk28 host11:0x%x\n", (unsigned)dwc_otg_device->base); + /* + * Attempt to ensure this device is really a DWC_otg Controller. + * Read and verify the SNPSID register contents. The value should be + * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX". + */ + snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40)); + if ((snpsid & 0xFFFFF000) != 0x4F542000) + { + DWC_PRINT("%s::snpsid=0x%x,want 0x%x" , __func__ , snpsid , 0x4F542000 ); + dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid); + retval = -EINVAL; + goto fail; + } + + /* + * Initialize driver data to point to the global DWC_otg + * Device structure. + */ + dev->platform_data = dwc_otg_device; + DWC_DEBUGPL(DBG_CIL, "dwc_otg_device=0x%p\n", dwc_otg_device); + g_host20 = dwc_otg_device; + + dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, + &host20_module_params); + if (dwc_otg_device->core_if == 0) + { + dev_err(dev, "CIL initialization failed!\n"); + retval = -ENOMEM; + goto fail; + } + + dwc_otg_device->core_if->otg_dev = dwc_otg_device; + /* + * Validate parameter values. + */ + if (check_parameters(dwc_otg_device->core_if) != 0) + { + retval = -EINVAL; + goto fail; + } + + /* + * Create Device Attributes in sysfs + */ + dwc_otg_attr_create(dev); + + /* + * Disable the global interrupt until all the interrupt + * handlers are installed. + */ + dwc_otg_disable_global_interrupts( dwc_otg_device->core_if ); + /* + * Install the interrupt handler for the common interrupts before + * enabling common interrupts in core_init below. + */ + irq = platform_get_irq(to_platform_device(dev),0); + DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", + irq); + retval = request_irq(irq, dwc_otg_common_irq, + IRQF_SHARED, "dwc_otg", dwc_otg_device ); + if (retval != 0) + { + DWC_ERROR("request of irq%d failed\n", irq); + retval = -EBUSY; + goto fail; + } + else + { + dwc_otg_device->common_irq_installed = 1; + } + + USB_IOMUX_INIT(GPIO4A6_OTG1DRVVBUS_NAME, GPIO4L_OTG1_DRV_VBUS); + /* + * Initialize the DWC_otg core. + */ + dwc_otg_core_init( dwc_otg_device->core_if ); + + /* + * Initialize the HCD + */ + retval = host20_hcd_init(dev); + if (retval != 0) + { + DWC_ERROR("host20_hcd_init failed\n"); + dwc_otg_device->hcd = NULL; + goto fail; + } + /* + * Enable the global interrupt after all the interrupt + * handlers are installed. + */ + dwc_otg_enable_global_interrupts( dwc_otg_device->core_if ); + DWC_PRINT("host20_driver_probe end, everest\n"); + return 0; + + fail: + devm_kfree(&pdev->dev, dwc_otg_device); + DWC_PRINT("host20_driver_probe fail,everest\n"); + return retval; +} + +static int host20_driver_suspend(struct platform_device *_dev , pm_message_t state ) +{ + //struct device *dev = &_dev->dev; + //dwc_otg_device_t *otg_dev = dev->platform_data; + //dwc_otg_core_if_t *core_if = otg_dev->core_if; + return 0; +} + +static int host20_driver_resume(struct platform_device *_dev ) +{ + //struct device *dev = &_dev->dev; + //dwc_otg_device_t *otg_dev = dev->platform_data; + //dwc_otg_core_if_t *core_if = otg_dev->core_if; + return 0; +} + +static struct platform_driver host20_driver = { + .probe = host20_driver_probe, + .remove = host20_driver_remove, + .suspend = host20_driver_suspend, + .resume = host20_driver_resume, + .driver = { + .name = "usb20_host", + .owner = THIS_MODULE}, +}; +#endif + /** * This function is called when the dwc_otg_driver is installed with the * insmod command. It registers the dwc_otg_driver structure with the @@ -1682,31 +1659,51 @@ static struct platform_driver rk28_host11_driver = { static int __init dwc_otg_driver_init(void) { int retval = 0; - - //*(unsigned long *)(0xFF040000+0xE00) = 0x0; //Enable USB Port + /* + * USB2.0 OTG controller + */ retval = platform_driver_register(&dwc_otg_driver); if (retval < 0) { - printk(KERN_ERR "%s retval=%d\n", __func__, retval); + DWC_ERROR("%s retval=%d\n", __func__, retval); return retval; } if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_version)) pr_warning("DWC_OTG: Failed to create driver version file\n"); if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_debuglevel)) pr_warning("DWC_OTG: Failed to create driver debug level file\n"); - -#ifdef DWC_BOTH_HOST_SLAVE - retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); + +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY + if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en)) + pr_warning("DWC_OTG: Failed to create driver dwc_otg_conn_en file"); + if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_vbus_status)) + pr_warning("DWC_OTG: Failed to create driver vbus status file"); #endif - -#ifdef CONFIG_RK2818_HOST11 - retval = platform_driver_register(&rk28_host11_driver); + + /* + * USB1.1 host controller + */ + +#ifdef CONFIG_USB11_HOST + retval = platform_driver_register(&host11_driver); if (retval < 0) { - printk(KERN_ERR "%s retval=%d\n", __func__, retval); + DWC_ERROR("%s retval=%d\n", __func__, retval); + return retval; + } +// retval = driver_create_file(&host11_driver.driver, &driver_attr_enable_usb11); +#endif + + /* + * USB1.1 host controller + */ +#ifdef CONFIG_USB20_HOST + retval = platform_driver_register(&host20_driver); + if (retval < 0) + { + DWC_ERROR("%s retval=%d\n", __func__, retval); return retval; } - retval = driver_create_file(&rk28_host11_driver.driver, &driver_attr_enable_usb11); #endif return retval; } @@ -1720,20 +1717,25 @@ module_init(dwc_otg_driver_init); */ static void __exit dwc_otg_driver_cleanup(void) { - printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n"); + DWC_PRINT("dwc_otg_driver_cleanup()\n"); driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version); driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel); -#ifdef DWC_BOTH_HOST_SLAVE - driver_remove_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode); + +#ifdef CONFIG_DWC_OTG_DEVICE_ONLY + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en); #endif platform_driver_unregister(&dwc_otg_driver); -#ifdef CONFIG_RK2818_HOST11 - platform_driver_unregister(&rk28_host11_driver); + +#ifdef CONFIG_USB11_HOST + platform_driver_unregister(&host11_driver); #endif - //*(unsigned long *)(0xFF040000+0xE00) = 0xF; //Disable USB Port - printk(KERN_INFO "%s module removed\n", dwc_driver_name); + +#ifdef CONFIG_USB20_HOST + platform_driver_unregister(&host20_driver); +#endif + DWC_PRINT("%s module removed\n", dwc_driver_name); } module_exit(dwc_otg_driver_cleanup); diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index 79502141b6f1..021b62b297d6 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -66,7 +66,7 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd) if(core_if->op_state == B_PERIPHERAL) { - printk("%s, usb device mode\n", __func__); + DWC_PRINT("%s, usb device mode\n", __func__); return 0; } hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); @@ -115,7 +115,7 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd) if(core_if->op_state == B_PERIPHERAL) { - printk("%s, usb device mode\n", __func__); + DWC_PRINT("%s, usb device mode\n", __func__); return 0; } #if 1 @@ -204,10 +204,48 @@ static const struct hc_driver dwc_otg_hc_driver = { //.hub_resume = }; -#ifdef CONFIG_RK2818_HOST11 -static const struct hc_driver rk28_host11_hc_driver = { +#ifdef CONFIG_USB11_HOST +static const struct hc_driver host11_hc_driver = { - .description = "rk28_host11_hcd", + .description = "host11_hcd", + .product_desc = "DWC OTG Controller", + .hcd_priv_size = sizeof(dwc_otg_hcd_t), + + .irq = dwc_otg_hcd_irq, + + .flags = HCD_MEMORY | HCD_USB2, + + //.reset = + .start = dwc_otg_hcd_start, + //.suspend = + //.resume = + + /* yk@rk 20100625 + * core/hcd.c call hcd->driver->bus_suspend + * otherwise system can not be suspended + */ +#ifdef CONFIG_PM + .bus_suspend = dwc_otg_hcd_suspend, + .bus_resume = dwc_otg_hcd_resume, +#endif + .stop = dwc_otg_hcd_stop, + + .urb_enqueue = dwc_otg_hcd_urb_enqueue, + .urb_dequeue = dwc_otg_hcd_urb_dequeue, + .endpoint_disable = dwc_otg_hcd_endpoint_disable, + + .get_frame_number = dwc_otg_hcd_get_frame_number, + + .hub_status_data = dwc_otg_hcd_hub_status_data, + .hub_control = dwc_otg_hcd_hub_control, + //.hub_suspend = + //.hub_resume = +}; +#endif +#ifdef CONFIG_USB20_HOST +static const struct hc_driver host20_hc_driver = { + + .description = "host20_hcd", .product_desc = "DWC OTG Controller", .hcd_priv_size = sizeof(dwc_otg_hcd_t), @@ -247,7 +285,6 @@ static const struct hc_driver rk28_host11_hc_driver = { * Work queue function for starting the HCD when A-Cable is connected. * The dwc_otg_hcd_start() must be called in a process context. */ -// cmy static void hcd_start_func(struct work_struct *work) { dwc_otg_hcd_t *dwc_otg_hcd = container_of(work, dwc_otg_hcd_t, start_work); @@ -381,7 +418,7 @@ static int32_t dwc_otg_hcd_disconnect_cb( void *_p ) /* * Set status flags for the hub driver. */ - printk("dwc_otg_hcd_disconnect_cb"); +// DWC_PRINT("dwc_otg_hcd_disconnect_cb"); dwc_otg_hcd->flags.b.port_connect_status_change = 1; dwc_otg_hcd->flags.b.port_connect_status = 0; @@ -572,20 +609,16 @@ int __devinit dwc_otg_hcd_init(struct device *dev) /* Set device flags indicating whether the HCD supports DMA. */ static u64 usb_dmamask = 0xffffffffUL; if (otg_dev->core_if->dma_enable) { -// DWC_PRINT("Using DMA mode\n"); dev->dma_mask = &usb_dmamask; dev->coherent_dma_mask = ~0; } else { -// DWC_PRINT("Using Slave mode\n"); dev->dma_mask = (void *)0; dev->coherent_dma_mask = 0; } #endif - printk("dwc_otg_hcd_init everest\n"); + DWC_PRINT("dwc_otg_hcd_init everest\n"); // g_dbg_lvl = 0xff; - DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); - /* * Allocate memory for the base HCD plus the DWC OTG HCD. * Initialize the base HCD. @@ -696,12 +729,12 @@ int __devinit dwc_otg_hcd_init(struct device *dev) usb_put_hcd(hcd); error1: - printk("dwc_otg_hcd_init error,everest\n"); + DWC_PRINT("dwc_otg_hcd_init error,everest\n"); return retval; } -#ifdef CONFIG_RK2818_HOST11 -static dwc_otg_cil_callbacks_t rk28_host11_cil_callbacks = { +#ifdef CONFIG_USB11_HOST +static dwc_otg_cil_callbacks_t host11_cil_callbacks = { .start = dwc_otg_hcd_start_cb, .stop = dwc_otg_hcd_stop_cb, .disconnect = dwc_otg_hcd_disconnect_cb, @@ -709,7 +742,7 @@ static dwc_otg_cil_callbacks_t rk28_host11_cil_callbacks = { .p = 0,//hcd }; -static struct tasklet_struct rk28_host11_reset_tasklet = { +static struct tasklet_struct host11_reset_tasklet = { .next = NULL, .state = 0, .count = ATOMIC_INIT(0), @@ -717,7 +750,7 @@ static struct tasklet_struct rk28_host11_reset_tasklet = { .data = 0, }; -int __devinit rk28_host11_hcd_init(struct device *dev) +int __devinit host11_hcd_init(struct device *dev) { struct usb_hcd *hcd = NULL; dwc_otg_hcd_t *dwc_otg_hcd = NULL; @@ -741,7 +774,7 @@ int __devinit rk28_host11_hcd_init(struct device *dev) dev->coherent_dma_mask = 0; } #endif - printk("%s everest\n",__func__); + DWC_PRINT("%s everest\n",__func__); // g_dbg_lvl = 0xff; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); @@ -750,7 +783,7 @@ int __devinit rk28_host11_hcd_init(struct device *dev) * Allocate memory for the base HCD plus the DWC OTG HCD. * Initialize the base HCD. */ - hcd = usb_create_hcd(&rk28_host11_hc_driver, dev, dev_name(dev)); + hcd = usb_create_hcd(&host11_hc_driver, dev, dev_name(dev)); if (hcd == NULL) { retval = -ENOMEM; goto error1; @@ -768,7 +801,7 @@ int __devinit rk28_host11_hcd_init(struct device *dev) /* Register the HCD CIL Callbacks */ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, - &rk28_host11_cil_callbacks, hcd); + &host11_cil_callbacks, hcd); /* Initialize the non-periodic schedule. */ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive); @@ -807,8 +840,8 @@ int __devinit rk28_host11_hcd_init(struct device *dev) init_timer( &dwc_otg_hcd->conn_timer ); /* Initialize reset tasklet. */ - rk28_host11_reset_tasklet.data = (unsigned long) dwc_otg_hcd; - dwc_otg_hcd->reset_tasklet = &rk28_host11_reset_tasklet; + host11_reset_tasklet.data = (unsigned long) dwc_otg_hcd; + dwc_otg_hcd->reset_tasklet = &host11_reset_tasklet; /* * Finish generic HCD initialization and start the HCD. This function * allocates the DMA buffer pool, registers the USB bus, requests the @@ -856,10 +889,171 @@ int __devinit rk28_host11_hcd_init(struct device *dev) usb_put_hcd(hcd); error1: - printk("dwc_otg_hcd_init error,everest\n"); + DWC_PRINT("dwc_otg_hcd_init error,everest\n"); return retval; } #endif +#ifdef CONFIG_USB20_HOST +static dwc_otg_cil_callbacks_t host20_cil_callbacks = { + .start = dwc_otg_hcd_start_cb, + .stop = dwc_otg_hcd_stop_cb, + .disconnect = dwc_otg_hcd_disconnect_cb, + .session_start = dwc_otg_hcd_session_start_cb, + .p = 0,//hcd +}; + +static struct tasklet_struct host20_reset_tasklet = { + .next = NULL, + .state = 0, + .count = ATOMIC_INIT(0), + .func = reset_tasklet_func, + .data = 0, +}; + +int __devinit host20_hcd_init(struct device *dev) +{ + struct usb_hcd *hcd = NULL; + dwc_otg_hcd_t *dwc_otg_hcd = NULL; + dwc_otg_device_t *otg_dev = dev->platform_data; + + int num_channels; + int i; + dwc_hc_t *channel; + + int retval = 0; +#if 1 //kaiker .these code must execute before usb_create_hcd + /* Set device flags indicating whether the HCD supports DMA. */ + static u64 usb_dmamask = 0xffffffffUL; + if (otg_dev->core_if->dma_enable) { +// DWC_PRINT("Using DMA mode\n"); + dev->dma_mask = &usb_dmamask; + dev->coherent_dma_mask = ~0; + } else { +// DWC_PRINT("Using Slave mode\n"); + dev->dma_mask = (void *)0; + dev->coherent_dma_mask = 0; + } +#endif + DWC_PRINT("%s everest\n",__func__); +// g_dbg_lvl = 0xff; + + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); + + /* + * Allocate memory for the base HCD plus the DWC OTG HCD. + * Initialize the base HCD. + */ + hcd = usb_create_hcd(&host20_hc_driver, dev, dev_name(dev)); + if (hcd == NULL) { + retval = -ENOMEM; + goto error1; + } + hcd->regs = otg_dev->base; + hcd->self.otg_port = 1; + + /* Initialize the DWC OTG HCD. */ + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); + dwc_otg_hcd->core_if = otg_dev->core_if; + otg_dev->hcd = dwc_otg_hcd; + + spin_lock_init(&dwc_otg_hcd->global_lock); + + + /* Register the HCD CIL Callbacks */ + dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, + &host20_cil_callbacks, hcd); + + /* Initialize the non-periodic schedule. */ + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive); + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active); + + /* Initialize the periodic schedule. */ + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned); + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued); + + /* + * Create a host channel descriptor for each host channel implemented + * in the controller. Initialize the channel descriptor array. + */ + INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list); + num_channels = dwc_otg_hcd->core_if->core_params->host_channels; + for (i = 0; i < num_channels; i++) { + channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL); + if (channel == NULL) { + retval = -ENOMEM; + DWC_ERROR("%s: host channel allocation failed\n", __func__); + goto error2; + } + memset(channel, 0, sizeof(dwc_hc_t)); + channel->hc_num = i; + dwc_otg_hcd->hc_ptr_array[i] = channel; +#ifdef DEBUG + init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]); +#endif + + DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel); + } + + /* Initialize the Connection timeout timer. */ + init_timer( &dwc_otg_hcd->conn_timer ); + + /* Initialize reset tasklet. */ + host20_reset_tasklet.data = (unsigned long) dwc_otg_hcd; + dwc_otg_hcd->reset_tasklet = &host20_reset_tasklet; + /* + * Finish generic HCD initialization and start the HCD. This function + * allocates the DMA buffer pool, registers the USB bus, requests the + * IRQ line, and calls dwc_otg_hcd_start method. + */ + retval = usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0), + IRQF_SHARED); + if (retval < 0) { + DWC_ERROR("usb_add_hcd fail,everest\n"); + goto error2; + } + /* + * Allocate space for storing data on status transactions. Normally no + * data is sent, but this space acts as a bit bucket. This must be + * done after usb_add_hcd since that function allocates the DMA buffer + * pool. + */ + if (otg_dev->core_if->dma_enable) { + dwc_otg_hcd->status_buf = + dma_alloc_coherent(dev, + DWC_OTG_HCD_STATUS_BUF_SIZE, + &dwc_otg_hcd->status_buf_dma, + GFP_KERNEL | GFP_DMA); + } else { + dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE, + GFP_KERNEL); + } + if (dwc_otg_hcd->status_buf == NULL) { + retval = -ENOMEM; + DWC_ERROR("%s: status_buf allocation failed\n", __func__); + goto error3; + } + + DWC_PRINT("%s end,everest\n",__func__); +// DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n", +// dev->bus_id, hcd->self.busnum); + + return 0; + + /* Error conditions */ + error3: + usb_remove_hcd(hcd); + error2: + dwc_otg_hcd_free(hcd); + usb_put_hcd(hcd); + + error1: + DWC_PRINT("dwc_otg_hcd_init error,everest\n"); + return retval; +} +#endif + /** * Removes the HCD. * Frees memory and resources associated with the HCD and deregisters the bus. @@ -934,32 +1128,11 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; unsigned long flags; - struct usb_device *udev; struct usb_bus *bus; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n"); spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -#if 0 - unsigned int regvalue; - printk("__________________________________________________________________\n"); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gotgint); - printk("gotgint is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gahbcfg); - printk("gahbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gusbcfg); - printk("gusbcfg is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->grstctl); - printk("grstctl is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintsts); - printk("gintsts is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk); - printk("gintmsk is %08x\n",regvalue); - regvalue = dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->gotgctl); - printk("gotgctl is %08x\n",regvalue); - printk("__________________________________________________________________\n"); -#endif + DWC_PRINT("dwc_otg_hcd_start! everest\n"); bus = hcd_to_bus(_hcd); _hcd->state = HC_STATE_RUNNING; @@ -971,13 +1144,17 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) usb_hcd_resume_root_hub(_hcd); } else { + /* + * no use + * yk@rk 2010121 + struct usb_device *udev;6 udev = usb_alloc_dev(NULL, bus, 0); udev->speed = USB_SPEED_HIGH; if (!udev) { DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n"); return -ENODEV; } - + */ /* Not needed - VJ if ((retval = usb_hcd_register_root_hub(udev, _hcd)) != 0) { DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error registering %d\n", retval); @@ -988,7 +1165,7 @@ int dwc_otg_hcd_start(struct usb_hcd *_hcd) /* Initialize the bus state. If the core is in Device Mode * HALT the USB bus and return. */ if (dwc_otg_is_device_mode (core_if)) { - printk("dwc_otg_hcd_start controller in device mode,everest\n"); + DWC_PRINT("dwc_otg_hcd_start controller in device mode,everest\n"); //_hcd->state = HC_STATE_HALT; goto out; } @@ -1110,7 +1287,6 @@ void dwc_otg_hcd_free(struct usb_hcd *_hcd) #ifdef DEBUG static void dump_urb_info(struct urb *_urb, char* _fn_name) { - DWC_PRINT("%s, urb %p,%x\n", _fn_name, _urb,_urb); DWC_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe)); DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(_urb->pipe), (usb_pipein(_urb->pipe) ? "IN" : "OUT")); @@ -1219,7 +1395,7 @@ int dwc_otg_hcd_urb_enqueue(struct usb_hcd *_hcd, retval = usb_hcd_link_urb_to_ep(_hcd, _urb); if (retval) { - printk("%s, usb_hcd_link_urb_to_ep error\n", __func__); + DWC_PRINT("%s, usb_hcd_link_urb_to_ep error\n", __func__); return retval; } spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); @@ -1277,8 +1453,8 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status) urb_qtd = (dwc_otg_qtd_t *) _urb->hcpriv; if(_ep==NULL) { - printk("%s=====================================================\n",__func__); - printk("urb->ep is null\n"); + DWC_PRINT("%s=====================================================\n",__func__); + DWC_PRINT("urb->ep is null\n"); return -1; } qh = (dwc_otg_qh_t *) _ep->hcpriv; @@ -1288,7 +1464,11 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status) spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); return retval; } - + if(urb_qtd == NULL) + { + DWC_PRINT("%s,urb_qtd is null\n",__func__); + //return -1; + } dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd); #ifdef DEBUG @@ -2389,8 +2569,18 @@ static void assign_and_init_hc(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) if (urb->dev->speed == USB_SPEED_LOW) { hc->speed = DWC_OTG_EP_SPEED_LOW; + /* + * yk@rk 20101216 fix bandwidth check error when full/low speed + * device connected. + */ + _hcd->core_if->core_params->speed = DWC_SPEED_PARAM_FULL; } else if (urb->dev->speed == USB_SPEED_FULL) { hc->speed = DWC_OTG_EP_SPEED_FULL; + /* + * yk@rk 20101216 fix bandwidth check error when full/low speed + * device connected. warning: only support 1 device at root hub. + */ + _hcd->core_if->core_params->speed = DWC_SPEED_PARAM_FULL; } else { hc->speed = DWC_OTG_EP_SPEED_HIGH; } @@ -2574,10 +2764,6 @@ dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd) num_channels - _hcd->periodic_channels) && */ !list_empty(&_hcd->free_hc_list)) { - - if((num_channels > 2)&&(_hcd->non_periodic_channels >= - num_channels - _hcd->periodic_channels)) - break; qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry); assign_and_init_hc(_hcd, qh); diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c index 8e24b6173e05..150ec592d975 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c @@ -55,7 +55,7 @@ int32_t dwc_otg_hcd_handle_intr (dwc_otg_hcd_t *_dwc_otg_hcd) if (dwc_otg_is_host_mode(core_if)) { gintsts.d32 = dwc_otg_read_core_intr(core_if); if (!gintsts.d32) { - DWC_PRINT("%s,GINTSTS = 0\n",__func__); +// DWC_PRINT("%s,GINTSTS = 0\n",__func__); return 0; } @@ -196,7 +196,7 @@ int32_t dwc_otg_hcd_handle_sof_intr (dwc_otg_hcd_t *_hcd) * fix bug for alcro hub * do not send csplit after start_split_frame+4 */ - if(dwc_frame_num_gt(_hcd->frame_number, + if((qh->do_split)&&dwc_frame_num_gt(_hcd->frame_number, dwc_frame_num_inc(qh->start_split_frame, 4))) { qtd = list_entry(qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); @@ -792,19 +792,8 @@ static void release_channel(dwc_otg_hcd_t *_hcd, dwc_otg_transaction_type_e tr_type; int free_qtd; - int continue_trans = 0; - DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n", __func__, _hc->hc_num, _halt_status); - if((!_hc->halt_pending)|| -// (!list_empty(&_hcd->non_periodic_sched_inactive)) - (_hcd->core_if->core_params->host_channels > 2)|| - (!_hc->ep_is_in)|| - (_hc->ep_type != DWC_OTG_EP_TYPE_BULK) - ) - { - continue_trans = 1; - } switch (_halt_status) { case DWC_OTG_HC_XFER_URB_COMPLETE: free_qtd = 1; @@ -866,13 +855,11 @@ static void release_channel(dwc_otg_hcd_t *_hcd, */ break; } - if(continue_trans) - { - /* Try to queue more transfers now that there's a free channel. */ - tr_type = dwc_otg_hcd_select_transactions(_hcd); - if (tr_type != DWC_OTG_TRANSACTION_NONE) { - dwc_otg_hcd_queue_transactions(_hcd, tr_type); - } + + /* Try to queue more transfers now that there's a free channel. */ + tr_type = dwc_otg_hcd_select_transactions(_hcd); + if (tr_type != DWC_OTG_TRANSACTION_NONE) { + dwc_otg_hcd_queue_transactions(_hcd, tr_type); } /* * Make sure the start of frame interrupt is enabled now that @@ -1230,12 +1217,6 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd, * occurs. The core will continue transferring data. */ _qtd->error_count = 0; - //yk@rk 20100714 - #if 1 - if((_hcd->core_if->core_params->host_channels <= 2) - &&(!_hc->halt_pending)) - dwc_otg_hc_halt(_hcd->core_if, _hc, DWC_OTG_HC_XFER_NAK); - #endif goto handle_nak_done; } @@ -1274,7 +1255,6 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd, handle_nak_done: clear_hc_int(_hc_regs,nak); - if(_hcd->core_if->core_params->host_channels > 2) disable_hc_int(_hc_regs,nak); return 1; @@ -1734,23 +1714,6 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, hcint.d32 = dwc_read_reg32(&_hc_regs->hcint); hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk); - if((!hcint.b.xfercomp)&& - (_hcd->core_if->core_params->host_channels <= 2)&& - (_hc->halt_pending)&& - (_hc->ep_is_in)&& - (_hc->ep_type == DWC_OTG_EP_TYPE_BULK)) - { - if(hcint.b.ack && !hcintmsk.b.ack) - { - //DWC_PRINT("Halt pending, ack!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); - handle_hc_xfercomp_intr(_hcd, _hc, _hc_regs, _qtd); - return; - } - release_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK); - clear_hc_int(_hc_regs,chhltd); - return; - } - if (hcint.b.xfercomp) { /** @todo This is here because of a possible hardware bug. Spec * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT @@ -1800,7 +1763,7 @@ static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd, */ handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd); } else if(hcint.b.datatglerr){ - DWC_PRINT("%s, DATA toggle error\n"); + DWC_PRINT("%s, DATA toggle error, Channel %d\n",__func__, _hc->hc_num); dwc_debug(1); clear_hc_int(_hc_regs,chhltd); } else { diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c index 120080356f65..4c62f491e667 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c @@ -143,7 +143,7 @@ void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_ur * _urb->dev->tt->hub may be null */ if((_urb->dev->tt)&&(!_urb->dev->tt->hub)) - printk("%s tt->hub null!\n",__func__); + DWC_PRINT("%s tt->hub null!\n",__func__); if (((_urb->dev->speed == USB_SPEED_LOW) || (_urb->dev->speed == USB_SPEED_FULL)) && (_urb->dev->tt) && (_urb->dev->tt->hub)&& @@ -241,9 +241,9 @@ static int periodic_channel_available(dwc_otg_hcd_t *_hcd) * non-periodic transactions. */ int status; -/*yk@rk modified for usb host 1.1*/ #if 0 int num_channels; + num_channels = _hcd->core_if->core_params->host_channels; if ((_hcd->periodic_channels + _hcd->non_periodic_channels < num_channels) && (_hcd->periodic_channels < num_channels - 1)) { diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index 20ee3409bd06..c1fe4382d428 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -568,7 +568,7 @@ static int dwc_otg_pcd_ep_queue(struct usb_ep *_ep, /* 20091226,HSL@RK */ if ( !list_empty(&req->queue) ) { - printk("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name); + DWC_PRINT("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name); return -EINVAL; while(!list_empty(&req->queue) ) { ep = container_of(_ep, dwc_otg_pcd_ep_t, ep); @@ -1526,7 +1526,7 @@ int dwc_pcd_reset(dwc_otg_pcd_t *pcd) //rockchip_scu_reset_unit(12); dwc_otg_pcd_reinit( pcd ); dwc_otg_core_dev_init(core_if); - //printk("%s\n" , __func__ ); + //DWC_PRINT("%s\n" , __func__ ); dwc_otg_enable_global_interrupts( core_if ); return 0; } @@ -1589,7 +1589,7 @@ int dwc_otg_reset( void ) dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 1; dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); - //printk("%s::otg reset connect!!!\n" , __func__ ); + //DWC_PRINT("%s::otg reset connect!!!\n" , __func__ ); return 0; } void dwc_otg_msc_lock(void) @@ -1605,7 +1605,6 @@ void dwc_otg_msc_unlock(void) android_unlock_suspend(&usb_msc_lock); #endif } -extern int dwc_step; static void dwc_phy_reconnect(struct work_struct *work) { dwc_otg_pcd_t *pcd; @@ -1618,23 +1617,17 @@ static void dwc_phy_reconnect(struct work_struct *work) gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl ); if( gctrl.b.bsesvld ) { dwc_otg_msc_lock(); - pcd->vbus_status = 1; /* set after softconnect */ +// pcd->vbus_status = 1; /* set after softconnect */ pcd->conn_status++; dwc_pcd_reset(pcd); /* * Enable the global interrupt after all the interrupt * handlers are installed. */ - #if 0 - printk("debug while 1, please enter command to continue!\n"); - dwc_step = 1; - while(dwc_step) - mdelay(5); - #endif dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 0; dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); - printk("********soft connect!!!*****************************************\n"); + DWC_PRINT("********soft connect!!!*****************************************\n"); } } @@ -1654,19 +1647,24 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) if( gctrl.b.bsesvld ) { /* if usb not connect before ,then start connect */ if( _pcd->vbus_status == 0 ) { - printk("********soft disconnect*****************************************\n"); + DWC_PRINT("********vbus detect*********************************************\n"); +// _pcd->conn_status = + _pcd->vbus_status = 1; /* soft disconnect */ dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl ); dctl.b.sftdiscon = 1; dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 ); /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); - schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ + if(_pcd->conn_en) + { + schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ + } } else if((_pcd->conn_status>0)&&(_pcd->conn_status <3)) { dwc_otg_msc_unlock(); - printk("********soft reconnect******************************************\n"); + DWC_PRINT("********soft reconnect******************************************\n"); _pcd->vbus_status =0; /* soft disconnect */ @@ -1676,6 +1674,12 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) /* Clear any pending interrupts */ dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); } + else if((_pcd->conn_en)&&(_pcd->conn_status == 0)) + { + + schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */ + _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */ + } else if(_pcd->conn_status ==3) { //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*// @@ -1683,7 +1687,7 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) _pcd->conn_status++; } } else { - //printk("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status ); + //DWC_PRINT("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status ); _pcd->vbus_status = 0; if(_pcd->conn_status) { @@ -1702,7 +1706,7 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata ) } } - //printk("%s:restart check vbus timer\n" , __func__ ); + //DWC_PRINT("%s:restart check vbus timer\n" , __func__ ); add_timer(&_pcd->check_vbus_timer); local_irq_restore(flags); } @@ -1726,6 +1730,8 @@ int dwc_vbus_status( void ) dwc_otg_pcd_t *pcd = s_pcd; return pcd->vbus_status ; } +EXPORT_SYMBOL(dwc_vbus_status); + int dwc_otg_set_phy_status(uint8_t status) { dwc_otg_pcd_t *pcd = s_pcd; @@ -1744,7 +1750,7 @@ int dwc_otg_pcd_init(struct device *dev) dwc_otg_core_if_t *core_if = otg_dev->core_if; int retval = 0; int irq; - printk("dwc_otg_pcd_init,everest\n"); + DWC_PRINT("dwc_otg_pcd_init,everest\n"); /* * Allocate PCD structure */ @@ -1772,7 +1778,11 @@ int dwc_otg_pcd_init(struct device *dev) pcd->gadget.is_dualspeed = 0; pcd->gadget.is_otg = 0; pcd->driver = 0; - +#ifdef CONFIG_DWC_CONN_EN + pcd->conn_en = 1; +#else + pcd->conn_en = 0; +#endif /* Register the gadget device */ retval = device_register( &pcd->gadget.dev ); if(retval != 0) @@ -1825,7 +1835,7 @@ int dwc_otg_pcd_init(struct device *dev) if (pcd->setup_pkt == 0) { - printk("pcd->setup_pkt alloc fail,everest\n"); + DWC_PRINT("pcd->setup_pkt alloc fail,everest\n"); kfree (pcd); return -ENOMEM; } @@ -1951,7 +1961,7 @@ EXPORT_SYMBOL(usb_gadget_register_driver); */ int usb_gadget_unregister_driver(struct usb_gadget_driver *_driver) { - //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); + DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver); if (s_pcd == 0) { @@ -1974,18 +1984,4 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *_driver) return 0; } EXPORT_SYMBOL(usb_gadget_unregister_driver); -#else -int rk28_usb_suspend( int exitsuspend ) -{ - return 0; -} -int dwc_vbus_status( void ) -{ - return 0; -} -int get_msc_connect_flag( void ) -{ - return 0; -} - #endif /* DWC_HOST_ONLY */ diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.h b/drivers/usb/dwc_otg/dwc_otg_pcd.h index ec8f2f5790a0..7d44d18e391a 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.h +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.h @@ -192,8 +192,11 @@ typedef struct dwc_otg_pcd /** vbus status in device mode */ uint8_t vbus_status; + /** enable connect to PC in device mode */ + uint8_t conn_en; + /** connect status used during enumeration */ - int16_t conn_status; + int8_t conn_status; /** Timer for check vbus at usb suspend. * every 500 ms. */ struct timer_list check_vbus_timer; diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c index ed21e70295a5..ac3f936c8d47 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c @@ -1630,7 +1630,7 @@ static int32_t ep0_complete_request( dwc_otg_pcd_ep_t *_ep ) /* else if (req->req.zero) { - printk("%s--------------------------------------------------\n",__func__); + DWC_PRINT("%s--------------------------------------------------\n",__func__); req->req.actual = _ep->dwc_ep.xfer_count; //do_setup_in_status_phase (pcd); req->req.zero = 0; @@ -1777,7 +1777,7 @@ static void complete_ep( dwc_otg_pcd_ep_t *_ep ) } request_done(_ep, req, 0); } else { - printk("\n++++++FIND NULL req,ep=%s++++++++++\n" , _ep->ep.name ); + DWC_PRINT("\n++++++FIND NULL req,ep=%s++++++++++\n" , _ep->ep.name ); _ep->pcd->request_pending = 0; } _ep->dwc_ep.start_xfer_buff = 0; diff --git a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h index 74008b6a5728..5bc5f78f8aab 100755 --- a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h +++ b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h @@ -41,16 +41,20 @@ #include #include +#include #define GRF_REG_BASE RK29_GRF_BASE #define USB20_OTG0_BASE RK29_USBOTG0_PHYS #define USB20_OTG1_BASE RK29_USBOTG1_PHYS #define USB11_HOST_BASE RK29_USBHOST_PHYS #define USBOTG_SIZE RK29_USBOTG0_SIZE -#define USB_GRF_CON (GRF_REG_BASE+0X9C) -#define USB_CLKGATE_CON (RK29_CRU_BASE+0X60) +#define USB_GRF_CON (GRF_REG_BASE+0x9C) +#define USB_GRF_IOMUX (GRF_REG_BASE+0x68) +#define USB_CLKGATE_CON (RK29_CRU_BASE+0x60) +#define USB_CLKSEL_CON (RK29_CRU_BASE+0x18) #ifndef SCU_BASE_ADDR_VA #define SCU_BASE_ADDR_VA RK29_CRU_BASE #endif +#define USB_IOMUX_INIT(a,b) rk29_mux_api_set(a,b) /** * @file * @@ -220,7 +224,7 @@ static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new ) #define DBG_OFF 0 /** Prefix string for DWC_DEBUG print macros. */ -#define USB_DWC "DWC_otg: " +#define USB_DWC "DWC_OTG: " /** * Print a debug message when the Global debug level variable contains @@ -240,8 +244,8 @@ static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new ) * */ #ifdef DEBUG -//# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0) -# define DWC_DEBUGPL(lvl, x...) printk( ">>> " x ) +# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0) +//# define DWC_DEBUGPL(lvl, x...) printk( ">>> " x ) # define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x ) # define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl) diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 4e970cf0e29a..946cbcfbcfbf 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -2013,6 +2013,9 @@ static int __init usba_udc_probe(struct platform_device *pdev) } else { disable_irq(gpio_to_irq(udc->vbus_pin)); } + } else { + /* gpio_request fail so use -EINVAL for gpio_is_valid */ + udc->vbus_pin = -EINVAL; } } diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c old mode 100644 new mode 100755 index dbc394ae33c9..8bdf100be5dc --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include @@ -468,8 +469,7 @@ static void put_be32(u8 *buf, u32 val) static void set_msc_connect_flag( int connected ) { - //GPIOSetPinLevel(CHARGE_OK_PIN,GPIO_LOW); - printk("set usb_msc_connect status = %d 20100520\n" , connected); + printk("%s status = %d 20101216\n" , __func__, connected); if( usb_msc_connected == connected ) return; usb_msc_connected = connected;//usb mass storage is ok @@ -479,6 +479,7 @@ int get_msc_connect_flag( void ) { return usb_msc_connected; } +EXPORT_SYMBOL(get_msc_connect_flag); /*-------------------------------------------------------------------------*/ @@ -2936,10 +2937,63 @@ static void fsg_function_disable(struct usb_function *f) set_msc_connect_flag(0); } +static enum power_supply_property usb_props[] = { +// POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_ONLINE, +}; + +static int usb_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + #ifdef CONFIG_DWC_OTG_DEVICE_ONLY + val->intval = get_msc_connect_flag(); + #else + val->intval = 0; + #endif + break; + default: + return -EINVAL; + } + + return ret; +} + +int usb_power_supply_register(struct device* parent) +{ + struct power_supply *ps; + int retval = 0; + + ps = kzalloc(sizeof(*ps), GFP_KERNEL); + if (!ps) { + dev_err(parent, "failed to allocate power supply data\n"); + retval = -ENOMEM; + goto out; + } + ps->name = "usb"; + ps->type = POWER_SUPPLY_TYPE_USB; + ps->properties = usb_props; + ps->num_properties = ARRAY_SIZE(usb_props); + ps->get_property = usb_get_property; + ps->external_power_changed = NULL; + retval = power_supply_register(parent, ps); + if (retval) { + dev_err(parent, "failed to register battery\n"); + goto out; + } +out: + return retval; +} + static int __init fsg_probe(struct platform_device *pdev) { struct usb_mass_storage_platform_data *pdata = pdev->dev.platform_data; struct fsg_dev *fsg = the_fsg; + int retval = 0; fsg->pdev = pdev; printk(KERN_INFO "fsg_probe pdata: %p\n", pdata); @@ -2956,7 +3010,16 @@ static int __init fsg_probe(struct platform_device *pdev) fsg->nluns = pdata->nluns; } - return 0; + /* + * Initialize usb power supply + */ + retval = usb_power_supply_register(&pdev->dev); + if (retval != 0) + { + dev_err(&pdev->dev, "usb_power_supply_register failed\n"); + } + + return retval; } static struct platform_driver fsg_platform_driver = { diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index fa3d142ba64d..08a9a62a39e3 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -489,7 +489,7 @@ static int fsl_ep_enable(struct usb_ep *_ep, 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 */ + max = max & 0x7ff; /* bit 0~10 */ /* 3 transactions at most */ if (mult > 3) goto en_done; diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 48267bc0b2e0..33ac6acbdb78 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -291,9 +291,13 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, /* mandatory */ case OID_GEN_VENDOR_DESCRIPTION: pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); - length = strlen (rndis_per_dev_params [configNr].vendorDescr); - memcpy (outbuf, - rndis_per_dev_params [configNr].vendorDescr, length); + if ( rndis_per_dev_params [configNr].vendorDescr ) { + length = strlen (rndis_per_dev_params [configNr].vendorDescr); + memcpy (outbuf, + rndis_per_dev_params [configNr].vendorDescr, length); + } else { + outbuf[0] = 0; + } retval = 0; break; diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index adf8260c3a6a..9e5f9f1e47a2 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -535,17 +535,11 @@ static void gs_rx_push(unsigned long _port) list_move(&req->list, &port->read_pool); } - /* Push from tty to ldisc; this is immediate with low_latency, and - * may trigger callbacks to this driver ... so drop the spinlock. + /* Push from tty to ldisc; without low_latency set this is handled by + * a workqueue, so we won't get callbacks and can hold port_lock */ if (tty && do_push) { - spin_unlock_irq(&port->port_lock); tty_flip_buffer_push(tty); - wake_up_interruptible(&tty->read_wait); - spin_lock_irq(&port->port_lock); - - /* tty may have been closed */ - tty = port->port_tty; } @@ -783,11 +777,6 @@ static int gs_open(struct tty_struct *tty, struct file *file) port->open_count = 1; port->openclose = false; - /* low_latency means ldiscs work in tasklet context, without - * needing a workqueue schedule ... easier to keep up. - */ - tty->low_latency = 1; - /* if connected, start the I/O stream */ if (port->port_usb) { struct gserial *gser = port->port_usb; @@ -1194,6 +1183,7 @@ void gserial_cleanup(void) n_ports = 0; tty_unregister_driver(gs_tty_driver); + put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; pr_debug("%s: cleaned up ttyGS* support\n", __func__); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e18c6773809f..8198fc0e4ac6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd) */ ehci->periodic_size = DEFAULT_I_TDPS; INIT_LIST_HEAD(&ehci->cached_itd_list); + INIT_LIST_HEAD(&ehci->cached_sitd_list); if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) return retval; @@ -993,7 +994,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) /* endpoints can be iso streams. for now, we don't * accelerate iso completions ... so spin a while. */ - if (qh->hw->hw_info1 == 0) { + if (qh->hw == NULL) { ehci_vdbg (ehci, "iso delay\n"); goto idle_timeout; } @@ -1007,10 +1008,11 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) tmp && tmp != qh; tmp = tmp->qh_next.qh) continue; - /* periodic qh self-unlinks on empty */ - if (!tmp) - goto nogood; - unlink_async (ehci, qh); + /* periodic qh self-unlinks on empty, and a COMPLETING qh + * may already be unlinked. + */ + if (tmp) + unlink_async(ehci, qh); /* FALL THROUGH */ case QH_STATE_UNLINK: /* wait for hw to finish? */ case QH_STATE_UNLINK_WAIT: @@ -1027,7 +1029,6 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) } /* else FALL THROUGH */ default: -nogood: /* caller was supposed to have unlinked any requests; * that's not our job. just leak this memory. */ diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 698f46135d5e..6ac3976ef3b2 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -292,6 +292,16 @@ static int ehci_bus_resume (struct usb_hcd *hcd) /* manually resume the ports we suspended during bus_suspend() */ i = HCS_N_PORTS (ehci->hcs_params); while (i--) { + /* clear phy low power mode before resume */ + if (ehci->has_hostpc) { + u32 __iomem *hostpc_reg = + (u32 __iomem *)((u8 *)ehci->regs + + HOSTPC0 + 4 * (i & 0xff)); + temp = ehci_readl(ehci, hostpc_reg); + ehci_writel(ehci, temp & ~HOSTPC_PHCD, + hostpc_reg); + mdelay(5); + } temp = ehci_readl(ehci, &ehci->regs->port_status [i]); temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); if (test_bit(i, &ehci->bus_suspended) && @@ -676,6 +686,13 @@ static int ehci_hub_control ( if (temp & PORT_SUSPEND) { if ((temp & PORT_PE) == 0) goto error; + /* clear phy low power mode before resume */ + if (hostpc_reg) { + temp1 = ehci_readl(ehci, hostpc_reg); + ehci_writel(ehci, temp1 & ~HOSTPC_PHCD, + hostpc_reg); + mdelay(5); + } /* resume signaling for 20 msec */ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); ehci_writel(ehci, temp | PORT_RESUME, diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index aeda96e0af67..1f3f01eacaf0 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_qh *qh) static void ehci_mem_cleanup (struct ehci_hcd *ehci) { - free_cached_itd_list(ehci); + free_cached_lists(ehci); if (ehci->async) qh_put (ehci->async); ehci->async = NULL; diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 36f96da129f5..ab26c2be366a 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -192,17 +192,19 @@ ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) } rv = usb_add_hcd(hcd, irq, 0); - if (rv == 0) - return 0; + if (rv) + goto err_ehci; + return 0; + +err_ehci: + if (ehci->has_amcc_usb23) + iounmap(ehci->ohci_hcctrl_reg); iounmap(hcd->regs); err_ioremap: irq_dispose_mapping(irq); err_irq: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - - if (ehci->has_amcc_usb23) - iounmap(ehci->ohci_hcctrl_reg); err_rmr: usb_put_hcd(hcd); diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index a5535b5e3fe2..6746a8a794d4 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1121,8 +1121,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) urb->interval); } - /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ - } else if (unlikely (stream->hw_info1 != 0)) { + /* if dev->ep [epnum] is a QH, hw is set */ + } else if (unlikely (stream->hw != NULL)) { ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", urb->dev->devpath, epnum, usb_pipein(urb->pipe) ? "in" : "out"); @@ -1553,13 +1553,27 @@ itd_patch( static inline void itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) { - /* always prepend ITD/SITD ... only QH tree is order-sensitive */ - itd->itd_next = ehci->pshadow [frame]; - itd->hw_next = ehci->periodic [frame]; - ehci->pshadow [frame].itd = itd; + union ehci_shadow *prev = &ehci->pshadow[frame]; + __hc32 *hw_p = &ehci->periodic[frame]; + union ehci_shadow here = *prev; + __hc32 type = 0; + + /* skip any iso nodes which might belong to previous microframes */ + while (here.ptr) { + type = Q_NEXT_TYPE(ehci, *hw_p); + if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) + break; + prev = periodic_next_shadow(ehci, prev, type); + hw_p = shadow_next_periodic(ehci, &here, type); + here = *prev; + } + + itd->itd_next = here; + itd->hw_next = *hw_p; + prev->itd = itd; itd->frame = frame; wmb (); - ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); + *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } /* fit urb's itds into the selected schedule slot; activate as needed */ @@ -2113,13 +2127,27 @@ sitd_complete ( (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } iso_stream_put (ehci, stream); - /* OK to recycle this SITD now that its completion callback ran. */ + done: sitd->urb = NULL; - sitd->stream = NULL; - list_move(&sitd->sitd_list, &stream->free_list); - iso_stream_put(ehci, stream); - + if (ehci->clock_frame != sitd->frame) { + /* OK to recycle this SITD now. */ + sitd->stream = NULL; + list_move(&sitd->sitd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } else { + /* HW might remember this SITD, so we can't recycle it yet. + * Move it to a safe place until a new frame starts. + */ + list_move(&sitd->sitd_list, &ehci->cached_sitd_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; } @@ -2185,9 +2213,10 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, /*-------------------------------------------------------------------------*/ -static void free_cached_itd_list(struct ehci_hcd *ehci) +static void free_cached_lists(struct ehci_hcd *ehci) { struct ehci_itd *itd, *n; + struct ehci_sitd *sitd, *sn; list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { struct ehci_iso_stream *stream = itd->stream; @@ -2195,6 +2224,13 @@ static void free_cached_itd_list(struct ehci_hcd *ehci) list_move(&itd->itd_list, &stream->free_list); iso_stream_put(ehci, stream); } + + list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) { + struct ehci_iso_stream *stream = sitd->stream; + sitd->stream = NULL; + list_move(&sitd->sitd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } } /*-------------------------------------------------------------------------*/ @@ -2221,7 +2257,7 @@ scan_periodic (struct ehci_hcd *ehci) clock_frame = -1; } if (ehci->clock_frame != clock_frame) { - free_cached_itd_list(ehci); + free_cached_lists(ehci); ehci->clock_frame = clock_frame; } clock %= mod; @@ -2384,7 +2420,7 @@ scan_periodic (struct ehci_hcd *ehci) clock = now; clock_frame = clock >> 3; if (ehci->clock_frame != clock_frame) { - free_cached_itd_list(ehci); + free_cached_lists(ehci); ehci->clock_frame = clock_frame; } } else { diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2d85e21ff282..556c0b48f3ab 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -87,8 +87,9 @@ struct ehci_hcd { /* one per controller */ int next_uframe; /* scan periodic, start here */ unsigned periodic_sched; /* periodic activity count */ - /* list of itds completed while clock_frame was still active */ + /* list of itds & sitds completed while clock_frame was still active */ struct list_head cached_itd_list; + struct list_head cached_sitd_list; unsigned clock_frame; /* per root hub port */ @@ -195,7 +196,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) clear_bit (action, &ehci->actions); } -static void free_cached_itd_list(struct ehci_hcd *ehci); +static void free_cached_lists(struct ehci_hcd *ehci); /*-------------------------------------------------------------------------*/ @@ -394,9 +395,8 @@ struct ehci_iso_sched { * acts like a qh would, if EHCI had them for ISO. */ struct ehci_iso_stream { - /* first two fields match QH, but info1 == 0 */ - __hc32 hw_next; - __hc32 hw_info1; + /* first field matches ehci_hq, but is NULL */ + struct ehci_qh_hw *hw; u32 refcount; u8 bEndpointAddress; diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 32bbce9718f0..65cac8cc8921 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -697,7 +697,7 @@ static int ohci_hub_control ( u16 wLength ) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ports = hcd_to_bus (hcd)->root_hub->maxchild; + int ports = ohci->num_ports; u32 temp; int retval = 0; diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 100bf3d8437c..1f1d4fa6a778 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c @@ -327,7 +327,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) } i2c_adap = i2c_get_adapter(2); memset(&i2c_info, 0, sizeof(struct i2c_board_info)); - strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); + strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, normal_i2c); i2c_put_adapter(i2c_adap); @@ -411,7 +411,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) out2: clk_put(usb_clk); out1: - i2c_unregister_client(isp1301_i2c_client); + i2c_unregister_device(isp1301_i2c_client); isp1301_i2c_client = NULL; out_i2c_driver: i2c_del_driver(&isp1301_driver); @@ -430,7 +430,7 @@ static int usb_hcd_pnx4008_remove(struct platform_device *pdev) pnx4008_unset_usb_bits(); clk_disable(usb_clk); clk_put(usb_clk); - i2c_unregister_client(isp1301_i2c_client); + i2c_unregister_device(isp1301_i2c_client); isp1301_i2c_client = NULL; i2c_del_driver(&isp1301_driver); diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 9260c743baa6..e3548ee6681c 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) /* this function must be called with interrupt disabled */ static void free_usb_address(struct r8a66597 *r8a66597, - struct r8a66597_device *dev) + struct r8a66597_device *dev, int reset) { int port; @@ -430,7 +430,13 @@ static void free_usb_address(struct r8a66597 *r8a66597, dev->state = USB_STATE_DEFAULT; r8a66597->address_map &= ~(1 << dev->address); dev->address = 0; - dev_set_drvdata(&dev->udev->dev, NULL); + /* + * Only when resetting USB, it is necessary to erase drvdata. When + * a usb device with usb hub is disconnect, "dev->udev" is already + * freed on usb_desconnect(). So we cannot access the data. + */ + if (reset) + dev_set_drvdata(&dev->udev->dev, NULL); list_del(&dev->device_list); kfree(dev); @@ -1067,7 +1073,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port) struct r8a66597_device *dev = r8a66597->root_hub[port].dev; disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 0); start_root_hub_sampling(r8a66597, port, 0); } @@ -2085,7 +2091,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597, spin_lock_irqsave(&r8a66597->lock, flags); dev = get_r8a66597_device(r8a66597, addr); disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 0); put_child_connect_map(r8a66597, addr); spin_unlock_irqrestore(&r8a66597->lock, flags); } @@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, rh->port |= (1 << USB_PORT_FEAT_RESET); disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 1); r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, get_dvstctr_reg(port)); diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 99cd00fd3514..09197067fe6b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -735,6 +735,7 @@ static void uhci_stop(struct usb_hcd *hcd) uhci_hc_died(uhci); uhci_scan_schedule(uhci); spin_unlock_irq(&uhci->lock); + synchronize_irq(hcd->irq); del_timer_sync(&uhci->fsbr_timer); release_uhci(uhci); diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index ecc131c3fe33..78c4edac1db1 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -101,12 +101,15 @@ static inline int xhci_find_next_cap_offset(void __iomem *base, int ext_offset) next = readl(base + ext_offset); - if (ext_offset == XHCI_HCC_PARAMS_OFFSET) + if (ext_offset == XHCI_HCC_PARAMS_OFFSET) { /* Find the first extended capability */ next = XHCI_HCC_EXT_CAPS(next); - else + ext_offset = 0; + } else { /* Find the next extended capability */ next = XHCI_EXT_CAPS_NEXT(next); + } + if (!next) return 0; /* diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index 932f99938481..a24a92f7dbc0 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c @@ -96,6 +96,33 @@ int xhci_halt(struct xhci_hcd *xhci) STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); } +/* + * Set the run bit and wait for the host to be running. + */ +int xhci_start(struct xhci_hcd *xhci) +{ + u32 temp; + int ret; + + temp = xhci_readl(xhci, &xhci->op_regs->command); + temp |= (CMD_RUN); + xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", + temp); + xhci_writel(xhci, temp, &xhci->op_regs->command); + + /* + * Wait for the HCHalted Status bit to be 0 to indicate the host is + * running. + */ + ret = handshake(xhci, &xhci->op_regs->status, + STS_HALT, 0, XHCI_MAX_HALT_USEC); + if (ret == -ETIMEDOUT) + xhci_err(xhci, "Host took too long to start, " + "waited %u microseconds.\n", + XHCI_MAX_HALT_USEC); + return ret; +} + /* * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. * @@ -107,6 +134,7 @@ int xhci_reset(struct xhci_hcd *xhci) { u32 command; u32 state; + int ret; state = xhci_readl(xhci, &xhci->op_regs->status); if ((state & STS_HALT) == 0) { @@ -121,7 +149,17 @@ int xhci_reset(struct xhci_hcd *xhci) /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ xhci_to_hcd(xhci)->state = HC_STATE_HALT; - return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); + ret = handshake(xhci, &xhci->op_regs->command, + CMD_RESET, 0, 250 * 1000); + if (ret) + return ret; + + xhci_dbg(xhci, "Wait for controller to be ready for doorbell rings\n"); + /* + * xHCI cannot write to any doorbells or operational registers other + * than status until the "Controller Not Ready" flag is cleared. + */ + return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); } /* @@ -460,13 +498,11 @@ int xhci_run(struct usb_hcd *hcd) if (NUM_TEST_NOOPS > 0) doorbell = xhci_setup_one_noop(xhci); - temp = xhci_readl(xhci, &xhci->op_regs->command); - temp |= (CMD_RUN); - xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", - temp); - xhci_writel(xhci, temp, &xhci->op_regs->command); - /* Flush PCI posted writes */ - temp = xhci_readl(xhci, &xhci->op_regs->command); + if (xhci_start(xhci)) { + xhci_halt(xhci); + return -ENODEV; + } + xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); if (doorbell) (*doorbell)(xhci); @@ -1157,6 +1193,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, cmd_completion = &virt_dev->cmd_completion; cmd_status = &virt_dev->cmd_status; } + init_completion(cmd_completion); if (!ctx_change) ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, @@ -1413,6 +1450,8 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, kfree(virt_ep->stopped_td); xhci_ring_cmd_db(xhci); } + virt_ep->stopped_td = NULL; + virt_ep->stopped_trb = NULL; spin_unlock_irqrestore(&xhci->lock, flags); if (ret) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index b8fd270a8b0d..dd71f02d5ff4 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -496,6 +496,19 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, return EP_INTERVAL(interval); } +/* The "Mult" field in the endpoint context is only set for SuperSpeed devices. + * High speed endpoint descriptors can define "the number of additional + * transaction opportunities per microframe", but that goes in the Max Burst + * endpoint context field. + */ +static inline u32 xhci_get_endpoint_mult(struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp) + return 0; + return ep->ss_ep_comp->desc.bmAttributes; +} + static inline u32 xhci_get_endpoint_type(struct usb_device *udev, struct usb_host_endpoint *ep) { @@ -526,6 +539,36 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev, return type; } +/* Return the maximum endpoint service interval time (ESIT) payload. + * Basically, this is the maxpacket size, multiplied by the burst size + * and mult size. + */ +static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, + struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + int max_burst; + int max_packet; + + /* Only applies for interrupt or isochronous endpoints */ + if (usb_endpoint_xfer_control(&ep->desc) || + usb_endpoint_xfer_bulk(&ep->desc)) + return 0; + + if (udev->speed == USB_SPEED_SUPER) { + if (ep->ss_ep_comp) + return ep->ss_ep_comp->desc.wBytesPerInterval; + xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n"); + /* Assume no bursts, no multiple opportunities to send. */ + return ep->desc.wMaxPacketSize; + } + + max_packet = ep->desc.wMaxPacketSize & 0x3ff; + max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; + /* A 0 in max burst means 1 transfer per ESIT */ + return max_packet * (max_burst + 1); +} + int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_device *udev, @@ -537,6 +580,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_ring *ep_ring; unsigned int max_packet; unsigned int max_burst; + u32 max_esit_payload; ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); @@ -550,6 +594,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep); + ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep)); /* FIXME dig Mult and streams info out of ep companion desc */ @@ -595,6 +640,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, default: BUG(); } + max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); + ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload); + + /* + * XXX no idea how to calculate the average TRB buffer length for bulk + * endpoints, as the driver gives us no clue how big each scatter gather + * list entry (or buffer) is going to be. + * + * For isochronous and interrupt endpoints, we set it to the max + * available, until we have new API in the USB core to allow drivers to + * declare how much bandwidth they actually need. + * + * Normally, it would be calculated by taking the total of the buffer + * lengths in the TD and then dividing by the number of TRBs in a TD, + * including link TRBs, No-op TRBs, and Event data TRBs. Since we don't + * use Event Data TRBs, and we don't chain in a link TRB on short + * transfers, we're basically dividing by 1. + */ + ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload); + /* FIXME Debug endpoint context */ return 0; } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 821b7b4709de..6416a0fca012 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -124,7 +124,7 @@ static void next_trb(struct xhci_hcd *xhci, *seg = (*seg)->next; *trb = ((*seg)->trbs); } else { - *trb = (*trb)++; + (*trb)++; } } @@ -241,10 +241,27 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, int i; union xhci_trb *enq = ring->enqueue; struct xhci_segment *enq_seg = ring->enq_seg; + struct xhci_segment *cur_seg; + unsigned int left_on_ring; /* Check if ring is empty */ - if (enq == ring->dequeue) + if (enq == ring->dequeue) { + /* Can't use link trbs */ + left_on_ring = TRBS_PER_SEGMENT - 1; + for (cur_seg = enq_seg->next; cur_seg != enq_seg; + cur_seg = cur_seg->next) + left_on_ring += TRBS_PER_SEGMENT - 1; + + /* Always need one TRB free in the ring. */ + left_on_ring -= 1; + if (num_trbs > left_on_ring) { + xhci_warn(xhci, "Not enough room on ring; " + "need %u TRBs, %u TRBs left\n", + num_trbs, left_on_ring); + return 0; + } return 1; + } /* Make sure there's an extra empty TRB available */ for (i = 0; i <= num_trbs; ++i) { if (enq == ring->dequeue) @@ -333,7 +350,8 @@ static struct xhci_segment *find_trb_seg( while (cur_seg->trbs > trb || &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) { generic_trb = &cur_seg->trbs[TRBS_PER_SEGMENT - 1].generic; - if (TRB_TYPE(generic_trb->field[3]) == TRB_LINK && + if ((generic_trb->field[3] & TRB_TYPE_BITMASK) == + TRB_TYPE(TRB_LINK) && (generic_trb->field[3] & LINK_TOGGLE)) *cycle_state = ~(*cycle_state) & 0x1; cur_seg = cur_seg->next; @@ -389,7 +407,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, BUG(); trb = &state->new_deq_ptr->generic; - if (TRB_TYPE(trb->field[3]) == TRB_LINK && + if ((trb->field[3] & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK) && (trb->field[3] & LINK_TOGGLE)) state->new_cycle_state = ~(state->new_cycle_state) & 0x1; next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); @@ -548,6 +566,8 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, /* Otherwise just ring the doorbell to restart the ring */ ring_ep_doorbell(xhci, slot_id, ep_index); } + ep->stopped_td = NULL; + ep->stopped_trb = NULL; /* * Drop the lock and complete the URBs in the cancelled TD list. @@ -1065,8 +1085,13 @@ static int handle_tx_event(struct xhci_hcd *xhci, ep->stopped_td = td; ep->stopped_trb = event_trb; + xhci_queue_reset_ep(xhci, slot_id, ep_index); xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index); + + ep->stopped_td = NULL; + ep->stopped_trb = NULL; + xhci_ring_cmd_db(xhci); goto td_cleanup; default: @@ -1186,8 +1211,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, for (cur_trb = ep_ring->dequeue, cur_seg = ep_ring->deq_seg; cur_trb != event_trb; next_trb(xhci, ep_ring, &cur_seg, &cur_trb)) { - if (TRB_TYPE(cur_trb->generic.field[3]) != TRB_TR_NOOP && - TRB_TYPE(cur_trb->generic.field[3]) != TRB_LINK) + if ((cur_trb->generic.field[3] & + TRB_TYPE_BITMASK) != TRB_TYPE(TRB_TR_NOOP) && + (cur_trb->generic.field[3] & + TRB_TYPE_BITMASK) != TRB_TYPE(TRB_LINK)) td->urb->actual_length += TRB_LEN(cur_trb->generic.field[2]); } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 4b254b6fa245..db821e982100 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -609,6 +609,10 @@ struct xhci_ep_ctx { #define MAX_PACKET_MASK (0xffff << 16) #define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff) +/* tx_info bitmasks */ +#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) +#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) + /** * struct xhci_input_control_context diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 5720bfef6a38..49deeb6c3b52 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c @@ -195,11 +195,9 @@ static ssize_t get_port1_handler(struct device *dev, return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1); } -static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO, - get_port0_handler, set_port0_handler); +static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR, get_port0_handler, set_port0_handler); -static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO, - get_port1_handler, set_port1_handler); +static DEVICE_ATTR(port1, S_IRUGO | S_IWUSR, get_port1_handler, set_port1_handler); static int cypress_probe(struct usb_interface *interface, diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index e75bb87ee92b..02ff0405d746 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -552,6 +552,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, /* needed for power consumption */ struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc; + memset(&info, 0, sizeof(info)); /* directly from the descriptor */ info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); info.product = dev->product_id; diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 0025847743f3..cafbd1514275 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -2435,7 +2435,8 @@ sisusb_open(struct inode *inode, struct file *file) } if (!sisusb->devinit) { - if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { + if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH || + sisusb->sisusb_dev->speed == USB_SPEED_SUPER) { if (sisusb_init_gfxdevice(sisusb, 0)) { mutex_unlock(&sisusb->lock); dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n"); @@ -3007,6 +3008,7 @@ sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) #else x.sisusb_conactive = 0; #endif + memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved)); if (copy_to_user((void __user *)arg, &x, sizeof(x))) retval = -EFAULT; @@ -3167,7 +3169,7 @@ static int sisusb_probe(struct usb_interface *intf, sisusb->present = 1; - if (dev->speed == USB_SPEED_HIGH) { + if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) { int initscreen = 1; #ifdef INCL_SISUSB_CON if (sisusb_first_vc > 0 && @@ -3245,6 +3247,7 @@ static struct usb_device_id sisusb_table [] = { { USB_DEVICE(0x0711, 0x0902) }, { USB_DEVICE(0x0711, 0x0903) }, { USB_DEVICE(0x0711, 0x0918) }, + { USB_DEVICE(0x0711, 0x0920) }, { USB_DEVICE(0x182d, 0x021c) }, { USB_DEVICE(0x182d, 0x0269) }, { } diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 2e14102955c5..d509dcb29b38 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -85,7 +85,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed); +static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed); static int tv_probe(struct usb_interface *interface, const struct usb_device_id *id) diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 06cb71942dc7..9650de93a3d4 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c @@ -94,7 +94,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co change_color(led); \ return count; \ } \ -static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value); +static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value); show_set(blue); show_set(red); show_set(green); diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 3db255537e79..cd8726c30444 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -185,7 +185,7 @@ static ssize_t set_attr_##name(struct device *dev, \ \ return count; \ } \ -static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name); +static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name); static ssize_t show_attr_text(struct device *dev, struct device_attribute *attr, char *buf) @@ -216,7 +216,7 @@ static ssize_t set_attr_text(struct device *dev, return count; } -static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text); +static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text); static ssize_t show_attr_decimals(struct device *dev, struct device_attribute *attr, char *buf) @@ -265,8 +265,7 @@ static ssize_t set_attr_decimals(struct device *dev, return count; } -static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO, - show_attr_decimals, set_attr_decimals); +static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals); static ssize_t show_attr_textmode(struct device *dev, struct device_attribute *attr, char *buf) @@ -312,8 +311,7 @@ static ssize_t set_attr_textmode(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO, - show_attr_textmode, set_attr_textmode); +static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode); MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered); diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index a9f06d76960f..d6a2ef374d83 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1382,7 +1382,6 @@ static void iso_callback (struct urb *urb) break; } } - simple_free_urb (urb); ctx->pending--; if (ctx->pending == 0) { @@ -1499,6 +1498,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, } simple_free_urb (urbs [i]); + urbs[i] = NULL; context.pending--; context.submit_error = 1; break; @@ -1508,6 +1508,10 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, wait_for_completion (&context.done); + for (i = 0; i < param->sglen; i++) { + if (urbs[i]) + simple_free_urb(urbs[i]); + } /* * Isochronous transfers are expected to fail sometimes. As an * arbitrary limit, we will report an error if any submissions diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 10f3205798e8..9231b25d725a 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -971,7 +971,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, mutex_lock(&rp->fetch_lock); spin_lock_irqsave(&rp->b_lock, flags); - mon_free_buff(rp->b_vec, size/CHUNK_SIZE); + mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); kfree(rp->b_vec); rp->b_vec = vec; rp->b_size = size; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index fcec87ea709e..51e8f0f734a0 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -248,8 +248,10 @@ int __init musb_platform_init(struct musb *musb) usb_nop_xceiv_register(); musb->xceiv = otg_get_transceiver(); - if (!musb->xceiv) + if (!musb->xceiv) { + gpio_free(musb->config->gpio_vrsel); return -ENODEV; + } if (ANOMALY_05000346) { bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 74073f9a43f0..c6f5ee4575cf 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -577,11 +577,19 @@ static void rxstate(struct musb *musb, struct musb_request *req) { const u8 epnum = req->epnum; struct usb_request *request = &req->request; - struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; + struct musb_ep *musb_ep; void __iomem *epio = musb->endpoints[epnum].regs; unsigned fifo_count = 0; - u16 len = musb_ep->packet_sz; + u16 len; u16 csr = musb_readw(epio, MUSB_RXCSR); + struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; + + if (hw_ep->is_shared_fifo) + musb_ep = &hw_ep->ep_in; + else + musb_ep = &hw_ep->ep_out; + + len = musb_ep->packet_sz; /* We shouldn't get here while DMA is active, but we do... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { @@ -749,9 +757,15 @@ void musb_g_rx(struct musb *musb, u8 epnum) u16 csr; struct usb_request *request; void __iomem *mbase = musb->mregs; - struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; + struct musb_ep *musb_ep; void __iomem *epio = musb->endpoints[epnum].regs; struct dma_channel *dma; + struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; + + if (hw_ep->is_shared_fifo) + musb_ep = &hw_ep->ep_in; + else + musb_ep = &hw_ep->ep_out; musb_ep_select(mbase, epnum); @@ -1074,7 +1088,7 @@ struct free_record { /* * Context: controller locked, IRQs blocked. */ -static void musb_ep_restart(struct musb *musb, struct musb_request *req) +void musb_ep_restart(struct musb *musb, struct musb_request *req) { DBG(3, "<== %s request %p len %u on hw_ep%d\n", req->tx ? "TX/IN" : "RX/OUT", diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h index 59502da9f739..76711f2a451b 100644 --- a/drivers/usb/musb/musb_gadget.h +++ b/drivers/usb/musb/musb_gadget.h @@ -105,4 +105,6 @@ extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int); extern int musb_gadget_set_halt(struct usb_ep *ep, int value); +extern void musb_ep_restart(struct musb *, struct musb_request *); + #endif /* __MUSB_GADGET_H */ diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 067e5a95b149..53c04448a8b8 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -369,6 +369,7 @@ __acquires(musb->lock) ctrlrequest->wIndex & 0x0f; struct musb_ep *musb_ep; struct musb_hw_ep *ep; + struct musb_request *request; void __iomem *regs; int is_in; u16 csr; @@ -411,6 +412,14 @@ __acquires(musb->lock) csr); } + /* Maybe start the first request in the queue */ + request = to_musb_request( + next_request(musb_ep)); + if (!musb_ep->busy && request) { + DBG(3, "restarting the request\n"); + musb_ep_restart(musb, request); + } + /* select ep0 again */ musb_ep_select(mbase, 0); handled = 1; diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index bd254ec97d14..9f8f0d0443c7 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -56,11 +56,14 @@ static int cp210x_carrier_raised(struct usb_serial_port *p); static int debug; static struct usb_device_id id_table [] = { + { USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */ { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ + { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ + { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ @@ -72,9 +75,12 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */ { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ + { USB_DEVICE(0x10C4, 0x8044) }, /* Cygnal Debug Adapter */ + { USB_DEVICE(0x10C4, 0x804E) }, /* Software Bisque Paramount ME build-in converter */ { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */ { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ + { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ @@ -82,28 +88,35 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ + { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ + { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ + { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ + { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */ { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ - { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ + { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */ { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ + { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ @@ -114,7 +127,14 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ + { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ + { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ + { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */ + { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ + { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ + { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ + { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; @@ -207,8 +227,8 @@ static struct usb_serial_driver cp210x_device = { #define BITS_STOP_2 0x0002 /* CP210X_SET_BREAK */ -#define BREAK_ON 0x0000 -#define BREAK_OFF 0x0001 +#define BREAK_ON 0x0001 +#define BREAK_OFF 0x0000 /* CP210X_(SET_MHS|GET_MDMSTS) */ #define CONTROL_DTR 0x0001 diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 13a1b39f1590..d5556349db3b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -44,12 +44,13 @@ #include #include #include "ftdi_sio.h" +#include "ftdi_sio_ids.h" /* * Version Information */ #define DRIVER_VERSION "v1.5.0" -#define DRIVER_AUTHOR "Greg Kroah-Hartman , Bill Ryder , Kuba Ober " +#define DRIVER_AUTHOR "Greg Kroah-Hartman , Bill Ryder , Kuba Ober , Andreas Mohr" #define DRIVER_DESC "USB FTDI Serial Converters Driver" static int debug; @@ -144,10 +145,15 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { +/* + * Device ID not listed? Test via module params product/vendor or + * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! + */ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, @@ -156,6 +162,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_USINT_CAT_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_USINT_WKEY_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_USINT_RS232_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, @@ -173,9 +182,11 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, + { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, @@ -195,6 +206,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, + { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, @@ -551,9 +563,16 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, /* - * Due to many user requests for multiple ELV devices we enable - * them by default. + * ELV devices: */ + { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_WS550_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_EC3000_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_WS888_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_TWS550_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_FEM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, @@ -570,11 +589,17 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_UTP8_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_WS444PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_UMS100_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) }, { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, @@ -595,6 +620,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, + { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, @@ -638,6 +664,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, + { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, @@ -655,7 +682,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, - { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) }, { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) }, @@ -676,6 +702,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, @@ -695,7 +723,37 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, + + /* Papouch devices based on FTDI chip */ + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485_2_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AP485_2_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB422_2_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485S_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB485C_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_LEC_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SB232_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_IRAMP_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK5_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO8x8_PID) }, { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x2_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO10x1_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO30x3_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO60x3_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO2x16_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO3x32_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_DRAK6_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_UPSUSB_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_MU_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_SIMUKEY_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMUX_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_GMSR_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, @@ -717,6 +775,35 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, + { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, + { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, + { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, + { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_ST_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, + { USB_DEVICE(FTDI_VID, ACCESIO_COM4SM_PID) }, + { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MIDI_TIMECODE_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MINI_WING_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, + { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -1371,7 +1458,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) } /* set max packet size based on descriptor */ - priv->max_packet_size = ep_desc->wMaxPacketSize; + priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize); dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); } diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 4586a24fafb0..b0e0d64f822e 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -1,7 +1,10 @@ /* - * Definitions for the FTDI USB Single Port Serial Converter - + * Driver definitions for the FTDI USB Single Port Serial Converter - * known as FTDI_SIO (Serial Input/Output application of the chipset) * + * For USB vendor/product IDs (VID/PID), please see ftdi_sio_ids.h + * + * * The example I have is known as the USC-1000 which is available from * http://www.dse.co.nz - cat no XH4214 It looks similar to this: * http://www.dansdata.com/usbser.htm but I can't be sure There are other @@ -17,881 +20,8 @@ * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the * FTDI_SIO implementation. * - * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais - * from Rudolf Gugler - * */ -#define FTDI_VID 0x0403 /* Vendor Id */ -#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ -#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ -#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ -#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ -#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ -#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ -#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ -#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ -#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ -#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ - -/* Larsen and Brusgaard AltiTrack/USBtrack */ -#define LARSENBRUSGAARD_VID 0x0FD8 -#define LB_ALTITRACK_PID 0x0001 - -/* www.canusb.com Lawicel CANUSB device */ -#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ - -/* AlphaMicro Components AMC-232USB01 device */ -#define FTDI_AMC232_PID 0xFF00 /* Product Id */ - -/* www.candapter.com Ewert Energy Systems CANdapter device */ -#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ - -/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ -/* the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ -#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ -#define FTDI_SCS_DEVICE_2_PID 0xD012 -#define FTDI_SCS_DEVICE_3_PID 0xD013 -#define FTDI_SCS_DEVICE_4_PID 0xD014 -#define FTDI_SCS_DEVICE_5_PID 0xD015 -#define FTDI_SCS_DEVICE_6_PID 0xD016 -#define FTDI_SCS_DEVICE_7_PID 0xD017 - -/* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ -#define FTDI_ACTZWAVE_PID 0xF2D0 - - -/* www.starting-point-systems.com µChameleon device */ -#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ - -/* www.irtrans.de device */ -#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ - - -/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ -#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ - -/* iPlus device */ -#define FTDI_IPLUS_PID 0xD070 /* Product Id */ -#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ - -/* DMX4ALL DMX Interfaces */ -#define FTDI_DMX4ALL 0xC850 - -/* OpenDCC (www.opendcc.de) product id */ -#define FTDI_OPENDCC_PID 0xBFD8 -#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 -#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA -#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB - -/* Sprog II (Andrew Crosland's SprogII DCC interface) */ -#define FTDI_SPROG_II 0xF0C8 - -/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ -/* they use the ftdi chipset for the USB interface and the vendor id is the same */ -#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ -#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ -#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ -#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ -#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ -#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ -#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ -#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ - -/* Video Networks Limited / Homechoice in the UK use an ftdi-based device for their 1Mb */ -/* broadband internet service. The following PID is exhibited by the usb device supplied */ -/* (the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ - -/* - * PCDJ use ftdi based dj-controllers. The following PID is for their DAC-2 device - * http://www.pcdjhardware.com/DAC2.asp (PID sent by Wouter Paesen) - * (the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_PCDJ_DAC2_PID 0xFA88 - -/* - * The following are the values for the Matrix Orbital LCD displays, - * which are the FT232BM ( similar to the 8U232AM ) - */ -#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ -#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ - -/* OOCDlink by Joern Kaipf - * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ -#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ - -/* - * The following are the values for the Matrix Orbital FTDI Range - * Anything in this range will use an FT232RL. - */ -#define MTXORB_VID 0x1B3D -#define MTXORB_FTDI_RANGE_0100_PID 0x0100 -#define MTXORB_FTDI_RANGE_0101_PID 0x0101 -#define MTXORB_FTDI_RANGE_0102_PID 0x0102 -#define MTXORB_FTDI_RANGE_0103_PID 0x0103 -#define MTXORB_FTDI_RANGE_0104_PID 0x0104 -#define MTXORB_FTDI_RANGE_0105_PID 0x0105 -#define MTXORB_FTDI_RANGE_0106_PID 0x0106 -#define MTXORB_FTDI_RANGE_0107_PID 0x0107 -#define MTXORB_FTDI_RANGE_0108_PID 0x0108 -#define MTXORB_FTDI_RANGE_0109_PID 0x0109 -#define MTXORB_FTDI_RANGE_010A_PID 0x010A -#define MTXORB_FTDI_RANGE_010B_PID 0x010B -#define MTXORB_FTDI_RANGE_010C_PID 0x010C -#define MTXORB_FTDI_RANGE_010D_PID 0x010D -#define MTXORB_FTDI_RANGE_010E_PID 0x010E -#define MTXORB_FTDI_RANGE_010F_PID 0x010F -#define MTXORB_FTDI_RANGE_0110_PID 0x0110 -#define MTXORB_FTDI_RANGE_0111_PID 0x0111 -#define MTXORB_FTDI_RANGE_0112_PID 0x0112 -#define MTXORB_FTDI_RANGE_0113_PID 0x0113 -#define MTXORB_FTDI_RANGE_0114_PID 0x0114 -#define MTXORB_FTDI_RANGE_0115_PID 0x0115 -#define MTXORB_FTDI_RANGE_0116_PID 0x0116 -#define MTXORB_FTDI_RANGE_0117_PID 0x0117 -#define MTXORB_FTDI_RANGE_0118_PID 0x0118 -#define MTXORB_FTDI_RANGE_0119_PID 0x0119 -#define MTXORB_FTDI_RANGE_011A_PID 0x011A -#define MTXORB_FTDI_RANGE_011B_PID 0x011B -#define MTXORB_FTDI_RANGE_011C_PID 0x011C -#define MTXORB_FTDI_RANGE_011D_PID 0x011D -#define MTXORB_FTDI_RANGE_011E_PID 0x011E -#define MTXORB_FTDI_RANGE_011F_PID 0x011F -#define MTXORB_FTDI_RANGE_0120_PID 0x0120 -#define MTXORB_FTDI_RANGE_0121_PID 0x0121 -#define MTXORB_FTDI_RANGE_0122_PID 0x0122 -#define MTXORB_FTDI_RANGE_0123_PID 0x0123 -#define MTXORB_FTDI_RANGE_0124_PID 0x0124 -#define MTXORB_FTDI_RANGE_0125_PID 0x0125 -#define MTXORB_FTDI_RANGE_0126_PID 0x0126 -#define MTXORB_FTDI_RANGE_0127_PID 0x0127 -#define MTXORB_FTDI_RANGE_0128_PID 0x0128 -#define MTXORB_FTDI_RANGE_0129_PID 0x0129 -#define MTXORB_FTDI_RANGE_012A_PID 0x012A -#define MTXORB_FTDI_RANGE_012B_PID 0x012B -#define MTXORB_FTDI_RANGE_012C_PID 0x012C -#define MTXORB_FTDI_RANGE_012D_PID 0x012D -#define MTXORB_FTDI_RANGE_012E_PID 0x012E -#define MTXORB_FTDI_RANGE_012F_PID 0x012F -#define MTXORB_FTDI_RANGE_0130_PID 0x0130 -#define MTXORB_FTDI_RANGE_0131_PID 0x0131 -#define MTXORB_FTDI_RANGE_0132_PID 0x0132 -#define MTXORB_FTDI_RANGE_0133_PID 0x0133 -#define MTXORB_FTDI_RANGE_0134_PID 0x0134 -#define MTXORB_FTDI_RANGE_0135_PID 0x0135 -#define MTXORB_FTDI_RANGE_0136_PID 0x0136 -#define MTXORB_FTDI_RANGE_0137_PID 0x0137 -#define MTXORB_FTDI_RANGE_0138_PID 0x0138 -#define MTXORB_FTDI_RANGE_0139_PID 0x0139 -#define MTXORB_FTDI_RANGE_013A_PID 0x013A -#define MTXORB_FTDI_RANGE_013B_PID 0x013B -#define MTXORB_FTDI_RANGE_013C_PID 0x013C -#define MTXORB_FTDI_RANGE_013D_PID 0x013D -#define MTXORB_FTDI_RANGE_013E_PID 0x013E -#define MTXORB_FTDI_RANGE_013F_PID 0x013F -#define MTXORB_FTDI_RANGE_0140_PID 0x0140 -#define MTXORB_FTDI_RANGE_0141_PID 0x0141 -#define MTXORB_FTDI_RANGE_0142_PID 0x0142 -#define MTXORB_FTDI_RANGE_0143_PID 0x0143 -#define MTXORB_FTDI_RANGE_0144_PID 0x0144 -#define MTXORB_FTDI_RANGE_0145_PID 0x0145 -#define MTXORB_FTDI_RANGE_0146_PID 0x0146 -#define MTXORB_FTDI_RANGE_0147_PID 0x0147 -#define MTXORB_FTDI_RANGE_0148_PID 0x0148 -#define MTXORB_FTDI_RANGE_0149_PID 0x0149 -#define MTXORB_FTDI_RANGE_014A_PID 0x014A -#define MTXORB_FTDI_RANGE_014B_PID 0x014B -#define MTXORB_FTDI_RANGE_014C_PID 0x014C -#define MTXORB_FTDI_RANGE_014D_PID 0x014D -#define MTXORB_FTDI_RANGE_014E_PID 0x014E -#define MTXORB_FTDI_RANGE_014F_PID 0x014F -#define MTXORB_FTDI_RANGE_0150_PID 0x0150 -#define MTXORB_FTDI_RANGE_0151_PID 0x0151 -#define MTXORB_FTDI_RANGE_0152_PID 0x0152 -#define MTXORB_FTDI_RANGE_0153_PID 0x0153 -#define MTXORB_FTDI_RANGE_0154_PID 0x0154 -#define MTXORB_FTDI_RANGE_0155_PID 0x0155 -#define MTXORB_FTDI_RANGE_0156_PID 0x0156 -#define MTXORB_FTDI_RANGE_0157_PID 0x0157 -#define MTXORB_FTDI_RANGE_0158_PID 0x0158 -#define MTXORB_FTDI_RANGE_0159_PID 0x0159 -#define MTXORB_FTDI_RANGE_015A_PID 0x015A -#define MTXORB_FTDI_RANGE_015B_PID 0x015B -#define MTXORB_FTDI_RANGE_015C_PID 0x015C -#define MTXORB_FTDI_RANGE_015D_PID 0x015D -#define MTXORB_FTDI_RANGE_015E_PID 0x015E -#define MTXORB_FTDI_RANGE_015F_PID 0x015F -#define MTXORB_FTDI_RANGE_0160_PID 0x0160 -#define MTXORB_FTDI_RANGE_0161_PID 0x0161 -#define MTXORB_FTDI_RANGE_0162_PID 0x0162 -#define MTXORB_FTDI_RANGE_0163_PID 0x0163 -#define MTXORB_FTDI_RANGE_0164_PID 0x0164 -#define MTXORB_FTDI_RANGE_0165_PID 0x0165 -#define MTXORB_FTDI_RANGE_0166_PID 0x0166 -#define MTXORB_FTDI_RANGE_0167_PID 0x0167 -#define MTXORB_FTDI_RANGE_0168_PID 0x0168 -#define MTXORB_FTDI_RANGE_0169_PID 0x0169 -#define MTXORB_FTDI_RANGE_016A_PID 0x016A -#define MTXORB_FTDI_RANGE_016B_PID 0x016B -#define MTXORB_FTDI_RANGE_016C_PID 0x016C -#define MTXORB_FTDI_RANGE_016D_PID 0x016D -#define MTXORB_FTDI_RANGE_016E_PID 0x016E -#define MTXORB_FTDI_RANGE_016F_PID 0x016F -#define MTXORB_FTDI_RANGE_0170_PID 0x0170 -#define MTXORB_FTDI_RANGE_0171_PID 0x0171 -#define MTXORB_FTDI_RANGE_0172_PID 0x0172 -#define MTXORB_FTDI_RANGE_0173_PID 0x0173 -#define MTXORB_FTDI_RANGE_0174_PID 0x0174 -#define MTXORB_FTDI_RANGE_0175_PID 0x0175 -#define MTXORB_FTDI_RANGE_0176_PID 0x0176 -#define MTXORB_FTDI_RANGE_0177_PID 0x0177 -#define MTXORB_FTDI_RANGE_0178_PID 0x0178 -#define MTXORB_FTDI_RANGE_0179_PID 0x0179 -#define MTXORB_FTDI_RANGE_017A_PID 0x017A -#define MTXORB_FTDI_RANGE_017B_PID 0x017B -#define MTXORB_FTDI_RANGE_017C_PID 0x017C -#define MTXORB_FTDI_RANGE_017D_PID 0x017D -#define MTXORB_FTDI_RANGE_017E_PID 0x017E -#define MTXORB_FTDI_RANGE_017F_PID 0x017F -#define MTXORB_FTDI_RANGE_0180_PID 0x0180 -#define MTXORB_FTDI_RANGE_0181_PID 0x0181 -#define MTXORB_FTDI_RANGE_0182_PID 0x0182 -#define MTXORB_FTDI_RANGE_0183_PID 0x0183 -#define MTXORB_FTDI_RANGE_0184_PID 0x0184 -#define MTXORB_FTDI_RANGE_0185_PID 0x0185 -#define MTXORB_FTDI_RANGE_0186_PID 0x0186 -#define MTXORB_FTDI_RANGE_0187_PID 0x0187 -#define MTXORB_FTDI_RANGE_0188_PID 0x0188 -#define MTXORB_FTDI_RANGE_0189_PID 0x0189 -#define MTXORB_FTDI_RANGE_018A_PID 0x018A -#define MTXORB_FTDI_RANGE_018B_PID 0x018B -#define MTXORB_FTDI_RANGE_018C_PID 0x018C -#define MTXORB_FTDI_RANGE_018D_PID 0x018D -#define MTXORB_FTDI_RANGE_018E_PID 0x018E -#define MTXORB_FTDI_RANGE_018F_PID 0x018F -#define MTXORB_FTDI_RANGE_0190_PID 0x0190 -#define MTXORB_FTDI_RANGE_0191_PID 0x0191 -#define MTXORB_FTDI_RANGE_0192_PID 0x0192 -#define MTXORB_FTDI_RANGE_0193_PID 0x0193 -#define MTXORB_FTDI_RANGE_0194_PID 0x0194 -#define MTXORB_FTDI_RANGE_0195_PID 0x0195 -#define MTXORB_FTDI_RANGE_0196_PID 0x0196 -#define MTXORB_FTDI_RANGE_0197_PID 0x0197 -#define MTXORB_FTDI_RANGE_0198_PID 0x0198 -#define MTXORB_FTDI_RANGE_0199_PID 0x0199 -#define MTXORB_FTDI_RANGE_019A_PID 0x019A -#define MTXORB_FTDI_RANGE_019B_PID 0x019B -#define MTXORB_FTDI_RANGE_019C_PID 0x019C -#define MTXORB_FTDI_RANGE_019D_PID 0x019D -#define MTXORB_FTDI_RANGE_019E_PID 0x019E -#define MTXORB_FTDI_RANGE_019F_PID 0x019F -#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 -#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 -#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 -#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 -#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 -#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 -#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 -#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 -#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 -#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 -#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA -#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB -#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC -#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD -#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE -#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF -#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 -#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 -#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 -#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 -#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 -#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 -#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 -#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 -#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 -#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 -#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA -#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB -#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC -#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD -#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE -#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF -#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 -#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 -#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 -#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 -#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 -#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 -#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 -#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 -#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 -#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 -#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA -#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB -#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC -#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD -#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE -#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF -#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 -#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 -#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 -#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 -#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 -#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 -#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 -#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 -#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 -#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 -#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA -#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB -#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC -#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD -#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE -#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF -#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 -#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 -#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 -#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 -#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 -#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 -#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 -#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 -#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 -#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 -#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA -#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB -#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC -#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED -#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE -#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF -#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 -#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 -#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 -#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 -#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 -#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 -#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 -#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 -#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 -#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 -#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA -#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB -#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC -#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD -#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE -#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF - - - -/* Interbiometrics USB I/O Board */ -/* Developed for Interbiometrics by Rudolf Gugler */ -#define INTERBIOMETRICS_VID 0x1209 -#define INTERBIOMETRICS_IOBOARD_PID 0x1002 -#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 - -/* - * The following are the values for the Perle Systems - * UltraPort USB serial converters - */ -#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ - -/* - * The following are the values for the Sealevel SeaLINK+ adapters. - * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and - * removed some PIDs that don't seem to match any existing products.) - */ -#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ -#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ -#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ -#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ -#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ -#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ -#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ -#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ -#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ -#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ -#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ -#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ -#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ -#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ -#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ -#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ -#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ -#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ -#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ -#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ -#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ -#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ -#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ -#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ -#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ -#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ -#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ -#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ -#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ -#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ -#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ -#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ -#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ -#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ -#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ -#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ -#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ -#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ -#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ -#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ -#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ -#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ -#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ -#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ -#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ -#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ -#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ -#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ - -/* - * The following are the values for two KOBIL chipcard terminals. - */ -#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ -#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ -#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ - -/* - * Icom ID-1 digital transceiver - */ - -#define ICOM_ID1_VID 0x0C26 -#define ICOM_ID1_PID 0x0004 - -/* - * ASK.fr devices - */ -#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ - -/* - * FTDI USB UART chips used in construction projects from the - * Elektor Electronics magazine (http://elektor-electronics.co.uk) - */ -#define ELEKTOR_VID 0x0C7D -#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ - -/* - * DSS-20 Sync Station for Sony Ericsson P800 - */ -#define FTDI_DSS20_PID 0xFC82 - -/* - * Home Electronics (www.home-electro.com) USB gadgets - */ -#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ - -/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ -/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ -#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ - -/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ - -#define FTDI_TNC_X_PID 0xEBE0 - -/* - * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). - * All of these devices use FTDI's vendor ID (0x0403). - * - * The previously included PID for the UO 100 module was incorrect. - * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). - * - * Armin Laeuger originally sent the PID for the UM 100 module. - */ -#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ -#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ -#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ -#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ -#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ -/* Additional ELV PIDs that default to using the FTDI D2XX drivers on - * MS Windows, rather than the FTDI Virtual Com Port drivers. - * Maybe these will be easier to use with the libftdi/libusb user-space - * drivers, or possibly the Comedi drivers in some cases. */ -#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ -#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ -#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ -#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ -#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ -#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ -#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ -#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ -#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ -#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ -#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ -#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ -#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ -#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ -#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ -#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ -#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ -#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ -#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ -#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ -#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ -#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ -#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ - -/* - * Definitions for ID TECH (www.idt-net.com) devices - */ -#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ -#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ - -/* - * Definitions for Omnidirectional Control Technology, Inc. devices - */ -#define OCT_VID 0x0B39 /* OCT vendor ID */ -/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ -/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ -/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ -#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ - -/* an infrared receiver for user access control with IR tags */ -#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ - -/* - * Definitions for Artemis astronomical USB based cameras - * Check it at http://www.artemisccd.co.uk/ - */ -#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ - -/* - * Definitions for ATIK Instruments astronomical USB based cameras - * Check it at http://www.atik-instruments.com/ - */ -#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ -#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ -#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ -#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ -#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ - -/* - * Protego product ids - */ -#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ -#define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ -#define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ -#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ - -/* - * Gude Analog- und Digitalsysteme GmbH - */ -#define FTDI_GUDEADS_E808_PID 0xE808 -#define FTDI_GUDEADS_E809_PID 0xE809 -#define FTDI_GUDEADS_E80A_PID 0xE80A -#define FTDI_GUDEADS_E80B_PID 0xE80B -#define FTDI_GUDEADS_E80C_PID 0xE80C -#define FTDI_GUDEADS_E80D_PID 0xE80D -#define FTDI_GUDEADS_E80E_PID 0xE80E -#define FTDI_GUDEADS_E80F_PID 0xE80F -#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ -#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ -#define FTDI_GUDEADS_E88A_PID 0xE88A -#define FTDI_GUDEADS_E88B_PID 0xE88B -#define FTDI_GUDEADS_E88C_PID 0xE88C -#define FTDI_GUDEADS_E88D_PID 0xE88D -#define FTDI_GUDEADS_E88E_PID 0xE88E -#define FTDI_GUDEADS_E88F_PID 0xE88F - -/* - * Linx Technologies product ids - */ -#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ -#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ -#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ -#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ -#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ - -/* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ -/* unit for PIC16's/PIC18's */ -#define FTDI_CCSICDU20_0_PID 0xF9D0 -#define FTDI_CCSICDU40_1_PID 0xF9D1 -#define FTDI_CCSMACHX_2_PID 0xF9D2 -#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 -#define FTDI_CCSICDU64_4_PID 0xF9D4 -#define FTDI_CCSPRIME8_5_PID 0xF9D5 - -/* Inside Accesso contactless reader (http://www.insidefr.com) */ -#define INSIDE_ACCESSO 0xFAD0 - -/* - * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI - */ -#define INTREPID_VID 0x093C -#define INTREPID_VALUECAN_PID 0x0601 -#define INTREPID_NEOVI_PID 0x0701 - -/* - * Falcom Wireless Communications GmbH - */ -#define FALCOM_VID 0x0F94 /* Vendor Id */ -#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ -#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ - -/* - * SUUNTO product ids - */ -#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ - -/* - * Oceanic product ids - */ -#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ - -/* - * TTi (Thurlby Thandar Instruments) - */ -#define TTI_VID 0x103E /* Vendor Id */ -#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ - -/* - * Definitions for B&B Electronics products. - */ -#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ -#define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ -#define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ -#define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ -#define BANDB_USOPTL4_PID 0xAC11 -#define BANDB_USPTL4_PID 0xAC12 -#define BANDB_USO9ML2DR_2_PID 0xAC16 -#define BANDB_USO9ML2DR_PID 0xAC17 -#define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ -#define BANDB_USOPTL4DR_PID 0xAC19 -#define BANDB_485USB9F_2W_PID 0xAC25 -#define BANDB_485USB9F_4W_PID 0xAC26 -#define BANDB_232USB9M_PID 0xAC27 -#define BANDB_485USBTB_2W_PID 0xAC33 -#define BANDB_485USBTB_4W_PID 0xAC34 -#define BANDB_TTL5USB9M_PID 0xAC49 -#define BANDB_TTL3USB9M_PID 0xAC50 -#define BANDB_ZZ_PROG1_USB_PID 0xBA02 - -/* - * RM Michaelides CANview USB (http://www.rmcan.com) - * CAN fieldbus interface adapter, added by port GmbH www.port.de) - * Ian Abbott changed the macro names for consistency. - */ -#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ - -/* - * EVER Eco Pro UPS (http://www.ever.com.pl/) - */ - -#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ - -/* - * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, - * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices - * and I'm not entirely sure which are used by which. - */ -#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 -#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 - -/* - * Mobility Electronics products. - */ -#define MOBILITY_VID 0x1342 -#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ - -/* - * microHAM product IDs (http://www.microham.com). - * Submitted by Justin Burket (KL1RL) - * and Mike Studer (K6EEP) . - * Ian Abbott added a few more from the driver INF file. - */ -#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ -#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ -#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ -#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ -#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ -#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ -#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ -#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ - -/* - * Active Robots product ids. - */ -#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ - -/* - * Xsens Technologies BV products (http://www.xsens.com). - */ -#define XSENS_CONVERTER_0_PID 0xD388 -#define XSENS_CONVERTER_1_PID 0xD389 -#define XSENS_CONVERTER_2_PID 0xD38A -#define XSENS_CONVERTER_3_PID 0xD38B -#define XSENS_CONVERTER_4_PID 0xD38C -#define XSENS_CONVERTER_5_PID 0xD38D -#define XSENS_CONVERTER_6_PID 0xD38E -#define XSENS_CONVERTER_7_PID 0xD38F - -/* - * Teratronik product ids. - * Submitted by O. Wölfelschneider. - */ -#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ -#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ - -/* - * Evolution Robotics products (http://www.evolution.com/). - * Submitted by Shawn M. Lavelle. - */ -#define EVOLUTION_VID 0xDEEE /* Vendor ID */ -#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ -#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ -#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ -#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ - -/* Pyramid Computer GmbH */ -#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ - -/* - * NDI (www.ndigital.com) product ids - */ -#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ -#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ -#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ -#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ -#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ - -/* - * Posiflex inc retail equipment (http://www.posiflex.com.tw) - */ -#define POSIFLEX_VID 0x0d3a /* Vendor ID */ -#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ - -/* - * Westrex International devices submitted by Cory Lee - */ -#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ -#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ - -/* - * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) - */ -#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ - -/* - * Eclo (http://www.eclo.pt/) product IDs. - * PID 0xEA90 submitted by Martin Grill. - */ -#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ - -/* - * Papouch products (http://www.papouch.com/) - * Submitted by Folkert van Heusden - */ - -#define PAPOUCH_VID 0x5050 /* Vendor ID */ -#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ -#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ - -/* - * ACG Identification Technologies GmbH products (http://www.acg.de/). - * Submitted by anton -at- goto10 -dot- org. - */ -#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ - -/* - * Yost Engineering, Inc. products (www.yostengineering.com). - * PID 0xE050 submitted by Aaron Prose. - */ -#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ - -/* - * ThorLabs USB motor drivers - */ -#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ - -/* - * Testo products (http://www.testo.com/) - * Submitted by Colin Leroy - */ -#define TESTO_VID 0x128D -#define TESTO_USB_INTERFACE_PID 0x0001 - -/* - * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. - */ -#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ - -/* - * Tactrix OpenPort (ECU) devices. - * OpenPort 1.3M submitted by Donour Sizemore. - * OpenPort 1.3S and 1.3U submitted by Ian Abbott. - */ -#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ -#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ -#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ - -/* - * Telldus Technologies - */ -#define TELLDUS_VID 0x1781 /* Vendor ID */ -#define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ - -/* - * IBS elektronik product ids - * Submitted by Thomas Schleusener - */ -#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ -#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ -#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ -#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ -#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ -#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ -#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ -#define FTDI_IBS_PROD_PID 0xff3f /* future device */ - -/* - * MaxStream devices www.maxstream.net - */ -#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ - -/* Olimex */ -#define OLIMEX_VID 0x15BA -#define OLIMEX_ARM_USB_OCD_PID 0x0003 - -/* Luminary Micro Stellaris Boards, VID = FTDI_VID */ -/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ -#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 -#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 - -/* www.elsterelectricity.com Elster Unicom III Optical Probe */ -#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ - -/* - * The Mobility Lab (TML) - * Submitted by Pierre Castella - */ -#define TML_VID 0x1B91 /* Vendor ID */ -#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ - -/* Propox devices */ -#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 - -/* Rig Expert Ukraine devices */ -#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ - -/* Domintell products http://www.domintell.com */ -#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ -#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ - -/* Alti-2 products http://www.alti-2.com */ -#define ALTI2_VID 0x1BC9 -#define ALTI2_N3_PID 0x6001 /* Neptune 3 */ - /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ @@ -910,86 +40,6 @@ #define INTERFACE_C 3 #define INTERFACE_D 4 -/* - * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 - * Submitted by Harald Welte - */ -#define FIC_VID 0x1457 -#define FIC_NEO1973_DEBUG_PID 0x5118 - -/* - * RATOC REX-USB60F - */ -#define RATOC_VENDOR_ID 0x0584 -#define RATOC_PRODUCT_ID_USB60F 0xb020 - -/* - * DIEBOLD BCS SE923 - */ -#define DIEBOLD_BCS_SE923_PID 0xfb99 - -/* - * Atmel STK541 - */ -#define ATMEL_VID 0x03eb /* Vendor ID */ -#define STK541_PID 0x2109 /* Zigbee Controller */ - -/* - * Dresden Elektronic Sensor Terminal Board - */ -#define DE_VID 0x1cf1 /* Vendor ID */ -#define STB_PID 0x0001 /* Sensor Terminal Board */ -#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ - -/* - * Blackfin gnICE JTAG - * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice - */ -#define ADI_VID 0x0456 -#define ADI_GNICE_PID 0xF000 -#define ADI_GNICEPLUS_PID 0xF001 - -/* - * JETI SPECTROMETER SPECBOS 1201 - * http://www.jeti.com/products/sys/scb/scb1201.php - */ -#define JETI_VID 0x0c6c -#define JETI_SPC1201_PID 0x04b2 - -/* - * Marvell SheevaPlug - */ -#define MARVELL_VID 0x9e88 -#define MARVELL_SHEEVAPLUG_PID 0x9e8f - -#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ - -/* - * GN Otometrics (http://www.otometrics.com) - * Submitted by Ville Sundberg. - */ -#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ -#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ - -/* - * Bayer Ascensia Contour blood glucose meter USB-converter cable. - * http://winglucofacts.com/cables/ - */ -#define BAYER_VID 0x1A79 -#define BAYER_CONTOUR_CABLE_PID 0x6001 - -/* - * Marvell OpenRD Base, Client - * http://www.open-rd.org - * OpenRD Base, Client use VID 0x0403 - */ -#define MARVELL_OPENRD_PID 0x9e90 - -/* - * Hameg HO820 and HO870 interface (using VID 0x0403) - */ -#define HAMEG_HO820_PID 0xed74 -#define HAMEG_HO870_PID 0xed71 /* * BmRequestType: 1100 0000b @@ -1504,4 +554,3 @@ typedef enum { * B2..7 Length of message - (not including Byte 0) * */ - diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h new file mode 100644 index 000000000000..54d8fd12ef8e --- /dev/null +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -0,0 +1,1120 @@ +/* + * vendor/product IDs (VID/PID) of devices using FTDI USB serial converters. + * Please keep numerically sorted within individual areas, thanks! + * + * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais + * from Rudolf Gugler + * + */ + + +/**********************************/ +/***** devices using FTDI VID *****/ +/**********************************/ + + +#define FTDI_VID 0x0403 /* Vendor Id */ + + +/*** "original" FTDI device PIDs ***/ + +#define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ +#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ +#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ +#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ +#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ +#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ + + +/*** third-party PIDs (using FTDI_VID) ***/ + +/* + * Marvell OpenRD Base, Client + * http://www.open-rd.org + * OpenRD Base, Client use VID 0x0403 + */ +#define MARVELL_OPENRD_PID 0x9e90 + +/* www.candapter.com Ewert Energy Systems CANdapter device */ +#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ + +#define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ + +/* US Interface Navigator (http://www.usinterface.com/) */ +#define FTDI_USINT_CAT_PID 0xb810 /* Navigator CAT and 2nd PTT lines */ +#define FTDI_USINT_WKEY_PID 0xb811 /* Navigator WKEY and FSK lines */ +#define FTDI_USINT_RS232_PID 0xb812 /* Navigator RS232 and CONFIG lines */ + +/* OOCDlink by Joern Kaipf + * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ +#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ + +/* Luminary Micro Stellaris Boards, VID = FTDI_VID */ +/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ +#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 +#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 + +#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ + +/* OpenDCC (www.opendcc.de) product id */ +#define FTDI_OPENDCC_PID 0xBFD8 +#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 +#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA +#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB +#define FTDI_OPENDCC_GBM_PID 0xBFDC + +/* + * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) + */ +#define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ + +/* DMX4ALL DMX Interfaces */ +#define FTDI_DMX4ALL 0xC850 + +/* + * ASK.fr devices + */ +#define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ + +/* www.starting-point-systems.com µChameleon device */ +#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ + +/* + * Tactrix OpenPort (ECU) devices. + * OpenPort 1.3M submitted by Donour Sizemore. + * OpenPort 1.3S and 1.3U submitted by Ian Abbott. + */ +#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ +#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ +#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ + +/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ +/* the VID is the standard ftdi vid (FTDI_VID) */ +#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ +#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ +#define FTDI_SCS_DEVICE_2_PID 0xD012 +#define FTDI_SCS_DEVICE_3_PID 0xD013 +#define FTDI_SCS_DEVICE_4_PID 0xD014 +#define FTDI_SCS_DEVICE_5_PID 0xD015 +#define FTDI_SCS_DEVICE_6_PID 0xD016 +#define FTDI_SCS_DEVICE_7_PID 0xD017 + +/* iPlus device */ +#define FTDI_IPLUS_PID 0xD070 /* Product Id */ +#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ + +/* + * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. + */ +#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ + +/* Propox devices */ +#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 + +/* Lenz LI-USB Computer Interface. */ +#define FTDI_LENZ_LIUSB_PID 0xD780 + +/* Vardaan Enterprises Serial Interface VEUSB422R3 */ +#define FTDI_VARDAAN_PID 0xF070 + +/* + * Xsens Technologies BV products (http://www.xsens.com). + */ +#define XSENS_CONVERTER_0_PID 0xD388 +#define XSENS_CONVERTER_1_PID 0xD389 +#define XSENS_CONVERTER_2_PID 0xD38A +#define XSENS_CONVERTER_3_PID 0xD38B +#define XSENS_CONVERTER_4_PID 0xD38C +#define XSENS_CONVERTER_5_PID 0xD38D +#define XSENS_CONVERTER_6_PID 0xD38E +#define XSENS_CONVERTER_7_PID 0xD38F + +/* + * NDI (www.ndigital.com) product ids + */ +#define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ +#define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ +#define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ +#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ +#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ + +/* + * ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs + */ +#define FTDI_CHAMSYS_24_MASTER_WING_PID 0xDAF8 +#define FTDI_CHAMSYS_PC_WING_PID 0xDAF9 +#define FTDI_CHAMSYS_USB_DMX_PID 0xDAFA +#define FTDI_CHAMSYS_MIDI_TIMECODE_PID 0xDAFB +#define FTDI_CHAMSYS_MINI_WING_PID 0xDAFC +#define FTDI_CHAMSYS_MAXI_WING_PID 0xDAFD +#define FTDI_CHAMSYS_MEDIA_WING_PID 0xDAFE +#define FTDI_CHAMSYS_WING_PID 0xDAFF + +/* + * Westrex International devices submitted by Cory Lee + */ +#define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ +#define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ + +/* + * ACG Identification Technologies GmbH products (http://www.acg.de/). + * Submitted by anton -at- goto10 -dot- org. + */ +#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ + +/* + * Definitions for Artemis astronomical USB based cameras + * Check it at http://www.artemisccd.co.uk/ + */ +#define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ + +/* + * Definitions for ATIK Instruments astronomical USB based cameras + * Check it at http://www.atik-instruments.com/ + */ +#define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ +#define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ +#define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ +#define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ +#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ + +/* + * Yost Engineering, Inc. products (www.yostengineering.com). + * PID 0xE050 submitted by Aaron Prose. + */ +#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ + +/* + * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). + * All of these devices use FTDI's vendor ID (0x0403). + * Further IDs taken from ELV Windows .inf file. + * + * The previously included PID for the UO 100 module was incorrect. + * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). + * + * Armin Laeuger originally sent the PID for the UM 100 module. + */ +#define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ +#define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ +#define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ +#define FTDI_ELV_WS550_PID 0xE004 /* WS 550 */ +#define FTDI_ELV_EC3000_PID 0xE006 /* ENERGY CONTROL 3000 USB */ +#define FTDI_ELV_WS888_PID 0xE008 /* WS 888 */ +#define FTDI_ELV_TWS550_PID 0xE009 /* Technoline WS 550 */ +#define FTDI_ELV_FEM_PID 0xE00A /* Funk Energie Monitor */ +#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ +#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ +#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ +#define FTDI_ELV_UMS100_PID 0xE0EB /* ELV USB Master-Slave Schaltsteckdose UMS 100 */ +#define FTDI_ELV_TFD128_PID 0xE0EC /* ELV Temperatur-Feuchte-Datenlogger TFD 128 */ +#define FTDI_ELV_FM3RX_PID 0xE0ED /* ELV Messwertuebertragung FM3 RX */ +#define FTDI_ELV_WS777_PID 0xE0EE /* Conrad WS 777 */ +#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ +#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ +#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ +#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ +#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ +#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ +#define FTDI_ELV_UTP8_PID 0xE0F5 /* ELV UTP 8 */ +#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ +#define FTDI_ELV_WS444PC_PID 0xE0F7 /* Conrad WS 444 PC */ +#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ +#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ +#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ +#define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ +#define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ +#define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ +#define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ +#define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ +#define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ +#define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ +#define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ +#define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ +/* Additional ELV PIDs that default to using the FTDI D2XX drivers on + * MS Windows, rather than the FTDI Virtual Com Port drivers. + * Maybe these will be easier to use with the libftdi/libusb user-space + * drivers, or possibly the Comedi drivers in some cases. */ +#define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ +#define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ +#define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ +#define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ +#define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ + +/* + * EVER Eco Pro UPS (http://www.ever.com.pl/) + */ + +#define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ + +/* + * Active Robots product ids. + */ +#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ + +/* Pyramid Computer GmbH */ +#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ + +/* www.elsterelectricity.com Elster Unicom III Optical Probe */ +#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ + +/* + * Gude Analog- und Digitalsysteme GmbH + */ +#define FTDI_GUDEADS_E808_PID 0xE808 +#define FTDI_GUDEADS_E809_PID 0xE809 +#define FTDI_GUDEADS_E80A_PID 0xE80A +#define FTDI_GUDEADS_E80B_PID 0xE80B +#define FTDI_GUDEADS_E80C_PID 0xE80C +#define FTDI_GUDEADS_E80D_PID 0xE80D +#define FTDI_GUDEADS_E80E_PID 0xE80E +#define FTDI_GUDEADS_E80F_PID 0xE80F +#define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ +#define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ +#define FTDI_GUDEADS_E88A_PID 0xE88A +#define FTDI_GUDEADS_E88B_PID 0xE88B +#define FTDI_GUDEADS_E88C_PID 0xE88C +#define FTDI_GUDEADS_E88D_PID 0xE88D +#define FTDI_GUDEADS_E88E_PID 0xE88E +#define FTDI_GUDEADS_E88F_PID 0xE88F + +/* + * Eclo (http://www.eclo.pt/) product IDs. + * PID 0xEA90 submitted by Martin Grill. + */ +#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ + +/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ +#define FTDI_TNC_X_PID 0xEBE0 + +/* + * Teratronik product ids. + * Submitted by O. Wölfelschneider. + */ +#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ +#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ + +/* Rig Expert Ukraine devices */ +#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ + +/* + * Hameg HO820 and HO870 interface (using VID 0x0403) + */ +#define HAMEG_HO820_PID 0xed74 +#define HAMEG_HO870_PID 0xed71 + +/* + * MaxStream devices www.maxstream.net + */ +#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ + +/* + * microHAM product IDs (http://www.microham.com). + * Submitted by Justin Burket (KL1RL) + * and Mike Studer (K6EEP) . + * Ian Abbott added a few more from the driver INF file. + */ +#define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ +#define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ +#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ +#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ +#define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ +#define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ +#define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ +#define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ + +/* Domintell products http://www.domintell.com */ +#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ +#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ + +/* + * The following are the values for the Perle Systems + * UltraPort USB serial converters + */ +#define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ + +/* Sprog II (Andrew Crosland's SprogII DCC interface) */ +#define FTDI_SPROG_II 0xF0C8 + +/* an infrared receiver for user access control with IR tags */ +#define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ + +/* ACT Solutions HomePro ZWave interface + (http://www.act-solutions.com/HomePro.htm) */ +#define FTDI_ACTZWAVE_PID 0xF2D0 + +/* + * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, + * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices + * and I'm not entirely sure which are used by which. + */ +#define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 +#define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 + +/* + * Linx Technologies product ids + */ +#define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ +#define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ +#define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ +#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ +#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ + +/* + * Oceanic product ids + */ +#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ + +/* + * SUUNTO product ids + */ +#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ + +/* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ +/* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ +#define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ + +/* CCS Inc. ICDU/ICDU40 product ID - + * the FT232BM is used in an in-circuit-debugger unit for PIC16's/PIC18's */ +#define FTDI_CCSICDU20_0_PID 0xF9D0 +#define FTDI_CCSICDU40_1_PID 0xF9D1 +#define FTDI_CCSMACHX_2_PID 0xF9D2 +#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 +#define FTDI_CCSICDU64_4_PID 0xF9D4 +#define FTDI_CCSPRIME8_5_PID 0xF9D5 + +/* + * The following are the values for the Matrix Orbital LCD displays, + * which are the FT232BM ( similar to the 8U232AM ) + */ +#define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ +#define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ + +/* + * Home Electronics (www.home-electro.com) USB gadgets + */ +#define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ + +/* Inside Accesso contactless reader (http://www.insidefr.com) */ +#define INSIDE_ACCESSO 0xFAD0 + +/* + * ThorLabs USB motor drivers + */ +#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ + +/* + * Protego product ids + */ +#define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ +#define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ +#define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ +#define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ + +/* + * DSS-20 Sync Station for Sony Ericsson P800 + */ +#define FTDI_DSS20_PID 0xFC82 + +/* www.irtrans.de device */ +#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ + +/* + * RM Michaelides CANview USB (http://www.rmcan.com) (FTDI_VID) + * CAN fieldbus interface adapter, added by port GmbH www.port.de) + * Ian Abbott changed the macro names for consistency. + */ +#define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ +/* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ +#define FTDI_TTUSB_PID 0xFF20 /* Product Id */ + +#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 (FTDI_VID) */ + +#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ + +/* + * PCDJ use ftdi based dj-controllers. The following PID is + * for their DAC-2 device http://www.pcdjhardware.com/DAC2.asp + * (the VID is the standard ftdi vid (FTDI_VID), PID sent by Wouter Paesen) + */ +#define FTDI_PCDJ_DAC2_PID 0xFA88 + +#define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG (FTDI_VID) */ + +/* + * DIEBOLD BCS SE923 (FTDI_VID) + */ +#define DIEBOLD_BCS_SE923_PID 0xfb99 + +/* www.crystalfontz.com devices + * - thanx for providing free devices for evaluation ! + * they use the ftdi chipset for the USB interface + * and the vendor id is the same + */ +#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ +#define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ +#define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ +#define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ +#define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ +#define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ +#define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ +#define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ + +/* + * Video Networks Limited / Homechoice in the UK use an ftdi-based device + * for their 1Mb broadband internet service. The following PID is exhibited + * by the usb device supplied (the VID is the standard ftdi vid (FTDI_VID) + */ +#define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ + +/* AlphaMicro Components AMC-232USB01 device (FTDI_VID) */ +#define FTDI_AMC232_PID 0xFF00 /* Product Id */ + +/* + * IBS elektronik product ids (FTDI_VID) + * Submitted by Thomas Schleusener + */ +#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ +#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ +#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ +#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ +#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ +#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ +#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ +#define FTDI_IBS_PROD_PID 0xff3f /* future device */ +/* www.canusb.com Lawicel CANUSB device (FTDI_VID) */ +#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ + + + +/********************************/ +/** third-party VID/PID combos **/ +/********************************/ + + + +/* + * Atmel STK541 + */ +#define ATMEL_VID 0x03eb /* Vendor ID */ +#define STK541_PID 0x2109 /* Zigbee Controller */ + +/* + * Blackfin gnICE JTAG + * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice + */ +#define ADI_VID 0x0456 +#define ADI_GNICE_PID 0xF000 +#define ADI_GNICEPLUS_PID 0xF001 + +/* + * RATOC REX-USB60F + */ +#define RATOC_VENDOR_ID 0x0584 +#define RATOC_PRODUCT_ID_USB60F 0xb020 + +/* + * Contec products (http://www.contec.com) + * Submitted by Daniel Sangorrin + */ +#define CONTEC_VID 0x06CE /* Vendor ID */ +#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ + +/* + * Contec products (http://www.contec.com) + * Submitted by Daniel Sangorrin + */ +#define CONTEC_VID 0x06CE /* Vendor ID */ +#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ + +/* + * Definitions for B&B Electronics products. + */ +#define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ +#define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ +#define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ +#define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ +#define BANDB_USOPTL4_PID 0xAC11 +#define BANDB_USPTL4_PID 0xAC12 +#define BANDB_USO9ML2DR_2_PID 0xAC16 +#define BANDB_USO9ML2DR_PID 0xAC17 +#define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ +#define BANDB_USOPTL4DR_PID 0xAC19 +#define BANDB_485USB9F_2W_PID 0xAC25 +#define BANDB_485USB9F_4W_PID 0xAC26 +#define BANDB_232USB9M_PID 0xAC27 +#define BANDB_485USBTB_2W_PID 0xAC33 +#define BANDB_485USBTB_4W_PID 0xAC34 +#define BANDB_TTL5USB9M_PID 0xAC49 +#define BANDB_TTL3USB9M_PID 0xAC50 +#define BANDB_ZZ_PROG1_USB_PID 0xBA02 + +/* + * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI + */ +#define INTREPID_VID 0x093C +#define INTREPID_VALUECAN_PID 0x0601 +#define INTREPID_NEOVI_PID 0x0701 + +/* + * Definitions for ID TECH (www.idt-net.com) devices + */ +#define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ +#define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ + +/* + * Definitions for Omnidirectional Control Technology, Inc. devices + */ +#define OCT_VID 0x0B39 /* OCT vendor ID */ +/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ +/* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ +/* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ +#define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ + +/* + * Icom ID-1 digital transceiver + */ + +#define ICOM_ID1_VID 0x0C26 +#define ICOM_ID1_PID 0x0004 + +/* + * GN Otometrics (http://www.otometrics.com) + * Submitted by Ville Sundberg. + */ +#define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ +#define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ + +/* + * The following are the values for the Sealevel SeaLINK+ adapters. + * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and + * removed some PIDs that don't seem to match any existing products.) + */ +#define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ +#define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ +#define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ +#define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ +#define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ +#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ +#define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ +#define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ +#define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ +#define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ +#define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ +#define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ +#define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ +#define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ +#define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ +#define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ +#define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ +#define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ +#define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ +#define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ +#define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ +#define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ +#define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ +#define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ +#define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ +#define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ +#define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ +#define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ +#define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ +#define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ +#define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ +#define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ +#define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ +#define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ +#define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ +#define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ +#define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ +#define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ +#define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ +#define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ +#define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ +#define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ +#define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ +#define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ +#define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ +#define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ +#define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ +#define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ + +/* + * JETI SPECTROMETER SPECBOS 1201 + * http://www.jeti.com/products/sys/scb/scb1201.php + */ +#define JETI_VID 0x0c6c +#define JETI_SPC1201_PID 0x04b2 + +/* + * FTDI USB UART chips used in construction projects from the + * Elektor Electronics magazine (http://elektor-electronics.co.uk) + */ +#define ELEKTOR_VID 0x0C7D +#define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ + +/* + * Posiflex inc retail equipment (http://www.posiflex.com.tw) + */ +#define POSIFLEX_VID 0x0d3a /* Vendor ID */ +#define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ + +/* + * The following are the values for two KOBIL chipcard terminals. + */ +#define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ +#define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ +#define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ + +#define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ +#define FTDI_NF_RIC_PID 0x0001 /* Product Id */ + +/* + * Falcom Wireless Communications GmbH + */ +#define FALCOM_VID 0x0F94 /* Vendor Id */ +#define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ +#define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ + +/* Larsen and Brusgaard AltiTrack/USBtrack */ +#define LARSENBRUSGAARD_VID 0x0FD8 +#define LB_ALTITRACK_PID 0x0001 + +/* + * TTi (Thurlby Thandar Instruments) + */ +#define TTI_VID 0x103E /* Vendor Id */ +#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ + +/* Interbiometrics USB I/O Board */ +/* Developed for Interbiometrics by Rudolf Gugler */ +#define INTERBIOMETRICS_VID 0x1209 +#define INTERBIOMETRICS_IOBOARD_PID 0x1002 +#define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 + +/* + * Testo products (http://www.testo.com/) + * Submitted by Colin Leroy + */ +#define TESTO_VID 0x128D +#define TESTO_USB_INTERFACE_PID 0x0001 + +/* + * Mobility Electronics products. + */ +#define MOBILITY_VID 0x1342 +#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ + +/* + * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 + * Submitted by Harald Welte + */ +#define FIC_VID 0x1457 +#define FIC_NEO1973_DEBUG_PID 0x5118 + +/* Olimex */ +#define OLIMEX_VID 0x15BA +#define OLIMEX_ARM_USB_OCD_PID 0x0003 + +/* + * Telldus Technologies + */ +#define TELLDUS_VID 0x1781 /* Vendor ID */ +#define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ + +/* + * RT Systems programming cables for various ham radios + */ +#define RTSYSTEMS_VID 0x2100 /* Vendor ID */ +#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ +#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ + +/* + * Bayer Ascensia Contour blood glucose meter USB-converter cable. + * http://winglucofacts.com/cables/ + */ +#define BAYER_VID 0x1A79 +#define BAYER_CONTOUR_CABLE_PID 0x6001 + +/* + * The following are the values for the Matrix Orbital FTDI Range + * Anything in this range will use an FT232RL. + */ +#define MTXORB_VID 0x1B3D +#define MTXORB_FTDI_RANGE_0100_PID 0x0100 +#define MTXORB_FTDI_RANGE_0101_PID 0x0101 +#define MTXORB_FTDI_RANGE_0102_PID 0x0102 +#define MTXORB_FTDI_RANGE_0103_PID 0x0103 +#define MTXORB_FTDI_RANGE_0104_PID 0x0104 +#define MTXORB_FTDI_RANGE_0105_PID 0x0105 +#define MTXORB_FTDI_RANGE_0106_PID 0x0106 +#define MTXORB_FTDI_RANGE_0107_PID 0x0107 +#define MTXORB_FTDI_RANGE_0108_PID 0x0108 +#define MTXORB_FTDI_RANGE_0109_PID 0x0109 +#define MTXORB_FTDI_RANGE_010A_PID 0x010A +#define MTXORB_FTDI_RANGE_010B_PID 0x010B +#define MTXORB_FTDI_RANGE_010C_PID 0x010C +#define MTXORB_FTDI_RANGE_010D_PID 0x010D +#define MTXORB_FTDI_RANGE_010E_PID 0x010E +#define MTXORB_FTDI_RANGE_010F_PID 0x010F +#define MTXORB_FTDI_RANGE_0110_PID 0x0110 +#define MTXORB_FTDI_RANGE_0111_PID 0x0111 +#define MTXORB_FTDI_RANGE_0112_PID 0x0112 +#define MTXORB_FTDI_RANGE_0113_PID 0x0113 +#define MTXORB_FTDI_RANGE_0114_PID 0x0114 +#define MTXORB_FTDI_RANGE_0115_PID 0x0115 +#define MTXORB_FTDI_RANGE_0116_PID 0x0116 +#define MTXORB_FTDI_RANGE_0117_PID 0x0117 +#define MTXORB_FTDI_RANGE_0118_PID 0x0118 +#define MTXORB_FTDI_RANGE_0119_PID 0x0119 +#define MTXORB_FTDI_RANGE_011A_PID 0x011A +#define MTXORB_FTDI_RANGE_011B_PID 0x011B +#define MTXORB_FTDI_RANGE_011C_PID 0x011C +#define MTXORB_FTDI_RANGE_011D_PID 0x011D +#define MTXORB_FTDI_RANGE_011E_PID 0x011E +#define MTXORB_FTDI_RANGE_011F_PID 0x011F +#define MTXORB_FTDI_RANGE_0120_PID 0x0120 +#define MTXORB_FTDI_RANGE_0121_PID 0x0121 +#define MTXORB_FTDI_RANGE_0122_PID 0x0122 +#define MTXORB_FTDI_RANGE_0123_PID 0x0123 +#define MTXORB_FTDI_RANGE_0124_PID 0x0124 +#define MTXORB_FTDI_RANGE_0125_PID 0x0125 +#define MTXORB_FTDI_RANGE_0126_PID 0x0126 +#define MTXORB_FTDI_RANGE_0127_PID 0x0127 +#define MTXORB_FTDI_RANGE_0128_PID 0x0128 +#define MTXORB_FTDI_RANGE_0129_PID 0x0129 +#define MTXORB_FTDI_RANGE_012A_PID 0x012A +#define MTXORB_FTDI_RANGE_012B_PID 0x012B +#define MTXORB_FTDI_RANGE_012C_PID 0x012C +#define MTXORB_FTDI_RANGE_012D_PID 0x012D +#define MTXORB_FTDI_RANGE_012E_PID 0x012E +#define MTXORB_FTDI_RANGE_012F_PID 0x012F +#define MTXORB_FTDI_RANGE_0130_PID 0x0130 +#define MTXORB_FTDI_RANGE_0131_PID 0x0131 +#define MTXORB_FTDI_RANGE_0132_PID 0x0132 +#define MTXORB_FTDI_RANGE_0133_PID 0x0133 +#define MTXORB_FTDI_RANGE_0134_PID 0x0134 +#define MTXORB_FTDI_RANGE_0135_PID 0x0135 +#define MTXORB_FTDI_RANGE_0136_PID 0x0136 +#define MTXORB_FTDI_RANGE_0137_PID 0x0137 +#define MTXORB_FTDI_RANGE_0138_PID 0x0138 +#define MTXORB_FTDI_RANGE_0139_PID 0x0139 +#define MTXORB_FTDI_RANGE_013A_PID 0x013A +#define MTXORB_FTDI_RANGE_013B_PID 0x013B +#define MTXORB_FTDI_RANGE_013C_PID 0x013C +#define MTXORB_FTDI_RANGE_013D_PID 0x013D +#define MTXORB_FTDI_RANGE_013E_PID 0x013E +#define MTXORB_FTDI_RANGE_013F_PID 0x013F +#define MTXORB_FTDI_RANGE_0140_PID 0x0140 +#define MTXORB_FTDI_RANGE_0141_PID 0x0141 +#define MTXORB_FTDI_RANGE_0142_PID 0x0142 +#define MTXORB_FTDI_RANGE_0143_PID 0x0143 +#define MTXORB_FTDI_RANGE_0144_PID 0x0144 +#define MTXORB_FTDI_RANGE_0145_PID 0x0145 +#define MTXORB_FTDI_RANGE_0146_PID 0x0146 +#define MTXORB_FTDI_RANGE_0147_PID 0x0147 +#define MTXORB_FTDI_RANGE_0148_PID 0x0148 +#define MTXORB_FTDI_RANGE_0149_PID 0x0149 +#define MTXORB_FTDI_RANGE_014A_PID 0x014A +#define MTXORB_FTDI_RANGE_014B_PID 0x014B +#define MTXORB_FTDI_RANGE_014C_PID 0x014C +#define MTXORB_FTDI_RANGE_014D_PID 0x014D +#define MTXORB_FTDI_RANGE_014E_PID 0x014E +#define MTXORB_FTDI_RANGE_014F_PID 0x014F +#define MTXORB_FTDI_RANGE_0150_PID 0x0150 +#define MTXORB_FTDI_RANGE_0151_PID 0x0151 +#define MTXORB_FTDI_RANGE_0152_PID 0x0152 +#define MTXORB_FTDI_RANGE_0153_PID 0x0153 +#define MTXORB_FTDI_RANGE_0154_PID 0x0154 +#define MTXORB_FTDI_RANGE_0155_PID 0x0155 +#define MTXORB_FTDI_RANGE_0156_PID 0x0156 +#define MTXORB_FTDI_RANGE_0157_PID 0x0157 +#define MTXORB_FTDI_RANGE_0158_PID 0x0158 +#define MTXORB_FTDI_RANGE_0159_PID 0x0159 +#define MTXORB_FTDI_RANGE_015A_PID 0x015A +#define MTXORB_FTDI_RANGE_015B_PID 0x015B +#define MTXORB_FTDI_RANGE_015C_PID 0x015C +#define MTXORB_FTDI_RANGE_015D_PID 0x015D +#define MTXORB_FTDI_RANGE_015E_PID 0x015E +#define MTXORB_FTDI_RANGE_015F_PID 0x015F +#define MTXORB_FTDI_RANGE_0160_PID 0x0160 +#define MTXORB_FTDI_RANGE_0161_PID 0x0161 +#define MTXORB_FTDI_RANGE_0162_PID 0x0162 +#define MTXORB_FTDI_RANGE_0163_PID 0x0163 +#define MTXORB_FTDI_RANGE_0164_PID 0x0164 +#define MTXORB_FTDI_RANGE_0165_PID 0x0165 +#define MTXORB_FTDI_RANGE_0166_PID 0x0166 +#define MTXORB_FTDI_RANGE_0167_PID 0x0167 +#define MTXORB_FTDI_RANGE_0168_PID 0x0168 +#define MTXORB_FTDI_RANGE_0169_PID 0x0169 +#define MTXORB_FTDI_RANGE_016A_PID 0x016A +#define MTXORB_FTDI_RANGE_016B_PID 0x016B +#define MTXORB_FTDI_RANGE_016C_PID 0x016C +#define MTXORB_FTDI_RANGE_016D_PID 0x016D +#define MTXORB_FTDI_RANGE_016E_PID 0x016E +#define MTXORB_FTDI_RANGE_016F_PID 0x016F +#define MTXORB_FTDI_RANGE_0170_PID 0x0170 +#define MTXORB_FTDI_RANGE_0171_PID 0x0171 +#define MTXORB_FTDI_RANGE_0172_PID 0x0172 +#define MTXORB_FTDI_RANGE_0173_PID 0x0173 +#define MTXORB_FTDI_RANGE_0174_PID 0x0174 +#define MTXORB_FTDI_RANGE_0175_PID 0x0175 +#define MTXORB_FTDI_RANGE_0176_PID 0x0176 +#define MTXORB_FTDI_RANGE_0177_PID 0x0177 +#define MTXORB_FTDI_RANGE_0178_PID 0x0178 +#define MTXORB_FTDI_RANGE_0179_PID 0x0179 +#define MTXORB_FTDI_RANGE_017A_PID 0x017A +#define MTXORB_FTDI_RANGE_017B_PID 0x017B +#define MTXORB_FTDI_RANGE_017C_PID 0x017C +#define MTXORB_FTDI_RANGE_017D_PID 0x017D +#define MTXORB_FTDI_RANGE_017E_PID 0x017E +#define MTXORB_FTDI_RANGE_017F_PID 0x017F +#define MTXORB_FTDI_RANGE_0180_PID 0x0180 +#define MTXORB_FTDI_RANGE_0181_PID 0x0181 +#define MTXORB_FTDI_RANGE_0182_PID 0x0182 +#define MTXORB_FTDI_RANGE_0183_PID 0x0183 +#define MTXORB_FTDI_RANGE_0184_PID 0x0184 +#define MTXORB_FTDI_RANGE_0185_PID 0x0185 +#define MTXORB_FTDI_RANGE_0186_PID 0x0186 +#define MTXORB_FTDI_RANGE_0187_PID 0x0187 +#define MTXORB_FTDI_RANGE_0188_PID 0x0188 +#define MTXORB_FTDI_RANGE_0189_PID 0x0189 +#define MTXORB_FTDI_RANGE_018A_PID 0x018A +#define MTXORB_FTDI_RANGE_018B_PID 0x018B +#define MTXORB_FTDI_RANGE_018C_PID 0x018C +#define MTXORB_FTDI_RANGE_018D_PID 0x018D +#define MTXORB_FTDI_RANGE_018E_PID 0x018E +#define MTXORB_FTDI_RANGE_018F_PID 0x018F +#define MTXORB_FTDI_RANGE_0190_PID 0x0190 +#define MTXORB_FTDI_RANGE_0191_PID 0x0191 +#define MTXORB_FTDI_RANGE_0192_PID 0x0192 +#define MTXORB_FTDI_RANGE_0193_PID 0x0193 +#define MTXORB_FTDI_RANGE_0194_PID 0x0194 +#define MTXORB_FTDI_RANGE_0195_PID 0x0195 +#define MTXORB_FTDI_RANGE_0196_PID 0x0196 +#define MTXORB_FTDI_RANGE_0197_PID 0x0197 +#define MTXORB_FTDI_RANGE_0198_PID 0x0198 +#define MTXORB_FTDI_RANGE_0199_PID 0x0199 +#define MTXORB_FTDI_RANGE_019A_PID 0x019A +#define MTXORB_FTDI_RANGE_019B_PID 0x019B +#define MTXORB_FTDI_RANGE_019C_PID 0x019C +#define MTXORB_FTDI_RANGE_019D_PID 0x019D +#define MTXORB_FTDI_RANGE_019E_PID 0x019E +#define MTXORB_FTDI_RANGE_019F_PID 0x019F +#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 +#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 +#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 +#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 +#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 +#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 +#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 +#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 +#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 +#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 +#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA +#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB +#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC +#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD +#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE +#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF +#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 +#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 +#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 +#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 +#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 +#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 +#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 +#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 +#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 +#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 +#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA +#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB +#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC +#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD +#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE +#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF +#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 +#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 +#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 +#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 +#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 +#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 +#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 +#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 +#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 +#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 +#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA +#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB +#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC +#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD +#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE +#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF +#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 +#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 +#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 +#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 +#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 +#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 +#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 +#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 +#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 +#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 +#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA +#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB +#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC +#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD +#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE +#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF +#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 +#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 +#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 +#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 +#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 +#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 +#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 +#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 +#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 +#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 +#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA +#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB +#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC +#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED +#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE +#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF +#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 +#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 +#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 +#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 +#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 +#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 +#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 +#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 +#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 +#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 +#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA +#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB +#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC +#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD +#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE +#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF + + + +/* + * The Mobility Lab (TML) + * Submitted by Pierre Castella + */ +#define TML_VID 0x1B91 /* Vendor ID */ +#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ + +/* Alti-2 products http://www.alti-2.com */ +#define ALTI2_VID 0x1BC9 +#define ALTI2_N3_PID 0x6001 /* Neptune 3 */ + +/* + * Ionics PlugComputer + */ +#define IONICS_VID 0x1c0c +#define IONICS_PLUGCOMPUTER_PID 0x0102 + +/* + * 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 */ + +/* + * Papouch products (http://www.papouch.com/) + * Submitted by Folkert van Heusden + */ + +#define PAPOUCH_VID 0x5050 /* Vendor ID */ +#define PAPOUCH_SB485_PID 0x0100 /* Papouch SB485 USB-485/422 Converter */ +#define PAPOUCH_AP485_PID 0x0101 /* AP485 USB-RS485 Converter */ +#define PAPOUCH_SB422_PID 0x0102 /* Papouch SB422 USB-RS422 Converter */ +#define PAPOUCH_SB485_2_PID 0x0103 /* Papouch SB485 USB-485/422 Converter */ +#define PAPOUCH_AP485_2_PID 0x0104 /* AP485 USB-RS485 Converter */ +#define PAPOUCH_SB422_2_PID 0x0105 /* Papouch SB422 USB-RS422 Converter */ +#define PAPOUCH_SB485S_PID 0x0106 /* Papouch SB485S USB-485/422 Converter */ +#define PAPOUCH_SB485C_PID 0x0107 /* Papouch SB485C USB-485/422 Converter */ +#define PAPOUCH_LEC_PID 0x0300 /* LEC USB Converter */ +#define PAPOUCH_SB232_PID 0x0301 /* Papouch SB232 USB-RS232 Converter */ +#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ +#define PAPOUCH_IRAMP_PID 0x0500 /* Papouch IRAmp Duplex */ +#define PAPOUCH_DRAK5_PID 0x0700 /* Papouch DRAK5 */ +#define PAPOUCH_QUIDO8x8_PID 0x0800 /* Papouch Quido 8/8 Module */ +#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Papouch Quido 4/4 Module */ +#define PAPOUCH_QUIDO2x2_PID 0x0a00 /* Papouch Quido 2/2 Module */ +#define PAPOUCH_QUIDO10x1_PID 0x0b00 /* Papouch Quido 10/1 Module */ +#define PAPOUCH_QUIDO30x3_PID 0x0c00 /* Papouch Quido 30/3 Module */ +#define PAPOUCH_QUIDO60x3_PID 0x0d00 /* Papouch Quido 60(100)/3 Module */ +#define PAPOUCH_QUIDO2x16_PID 0x0e00 /* Papouch Quido 2/16 Module */ +#define PAPOUCH_QUIDO3x32_PID 0x0f00 /* Papouch Quido 3/32 Module */ +#define PAPOUCH_DRAK6_PID 0x1000 /* Papouch DRAK6 */ +#define PAPOUCH_UPSUSB_PID 0x8000 /* Papouch UPS-USB adapter */ +#define PAPOUCH_MU_PID 0x8001 /* MU controller */ +#define PAPOUCH_SIMUKEY_PID 0x8002 /* Papouch SimuKey */ +#define PAPOUCH_AD4USB_PID 0x8003 /* AD4USB Measurement Module */ +#define PAPOUCH_GMUX_PID 0x8004 /* Papouch GOLIATH MUX */ +#define PAPOUCH_GMSR_PID 0x8005 /* Papouch GOLIATH MSR */ + +/* + * Marvell SheevaPlug + */ +#define MARVELL_VID 0x9e88 +#define MARVELL_SHEEVAPLUG_PID 0x9e8f + +/* + * Evolution Robotics products (http://www.evolution.com/). + * Submitted by Shawn M. Lavelle. + */ +#define EVOLUTION_VID 0xDEEE /* Vendor ID */ +#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ +#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ +#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ +#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ + +/* + * MJS Gadgets HD Radio / XM Radio / Sirius Radio interfaces (using VID 0x0403) + */ +#define MJSG_GENERIC_PID 0x9378 +#define MJSG_SR_RADIO_PID 0x9379 +#define MJSG_XM_RADIO_PID 0x937A +#define MJSG_HD_RADIO_PID 0x937C + +/* + * Xverve Signalyzer tools (http://www.signalyzer.com/) + */ +#define XVERVE_SIGNALYZER_ST_PID 0xBCA0 +#define XVERVE_SIGNALYZER_SLITE_PID 0xBCA1 +#define XVERVE_SIGNALYZER_SH2_PID 0xBCA2 +#define XVERVE_SIGNALYZER_SH4_PID 0xBCA4 + +/* + * Segway Robotic Mobility Platform USB interface (using VID 0x0403) + * Submitted by John G. Rogers + */ +#define SEGWAY_RMP200_PID 0xe729 + + +/* + * Accesio USB Data Acquisition products (http://www.accesio.com/) + */ +#define ACCESIO_COM4SM_PID 0xD578 + +/* www.sciencescope.co.uk educational dataloggers */ +#define FTDI_SCIENCESCOPE_LOGBOOKML_PID 0xFF18 +#define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID 0xFF1C +#define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D + +/* + * Milkymist One JTAG/Serial + */ +#define QIHARDWARE_VID 0x20B7 +#define MILKYMISTONE_JTAGSERIAL_PID 0x0713 + diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index d4cc0f7af400..fbdbac5ae410 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1157,7 +1157,7 @@ static int download_fw(struct edgeport_serial *serial) /* Check if we have an old version in the I2C and update if necessary */ - if (download_cur_ver != download_new_ver) { + if (download_cur_ver < download_new_ver) { dbg("%s - Update I2C dld from %d.%d to %d.%d", __func__, firmware_version->Ver_Major, diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 95d8d26b9a44..2e0497b02260 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -312,6 +312,7 @@ static int ir_open(struct tty_struct *tty, struct usb_serial_port *port) kfree(port->read_urb->transfer_buffer); port->read_urb->transfer_buffer = buffer; port->read_urb->transfer_buffer_length = buffer_size; + port->bulk_in_buffer = buffer; buffer = kmalloc(buffer_size, GFP_KERNEL); if (!buffer) { @@ -321,6 +322,7 @@ static int ir_open(struct tty_struct *tty, struct usb_serial_port *port) kfree(port->write_urb->transfer_buffer); port->write_urb->transfer_buffer = buffer; port->write_urb->transfer_buffer_length = buffer_size; + port->bulk_out_buffer = buffer; port->bulk_out_size = buffer_size; } diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 3a7873806f46..682508289b44 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -310,6 +310,7 @@ static int klsi_105_startup(struct usb_serial *serial) usb_free_urb(priv->write_urb_pool[j]); } } + kfree(priv); usb_set_serial_port_data(serial->port[i], NULL); } return -ENOMEM; diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 45ea694b3ae6..9d99e682f96d 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -345,7 +345,8 @@ static void kobil_close(struct usb_serial_port *port) /* FIXME: Add rts/dtr methods */ if (port->write_urb) { - usb_kill_urb(port->write_urb); + usb_poison_urb(port->write_urb); + kfree(port->write_urb->transfer_buffer); usb_free_urb(port->write_urb); port->write_urb = NULL; } diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 763e32a44be0..f3a73e7b948c 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1466,6 +1466,9 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file, case TIOCGICOUNT: cnow = mos7720_port->icount; + + memset(&icount, 0, sizeof(struct serial_icounter_struct)); + icount.cts = cnow.cts; icount.dsr = cnow.dsr; icount.rng = cnow.rng; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 485fa9c5b107..9fdcee2eca99 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -120,15 +120,20 @@ * by making a change here, in moschip_port_id_table, and in * moschip_id_table_combined */ -#define USB_VENDOR_ID_BANDB 0x0856 -#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 -#define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 -#define BANDB_DEVICE_ID_US9ML2_2 0xAC29 -#define BANDB_DEVICE_ID_US9ML2_4 0xAC30 -#define BANDB_DEVICE_ID_USPTL4_2 0xAC31 -#define BANDB_DEVICE_ID_USPTL4_4 0xAC32 -#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 -#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 +#define USB_VENDOR_ID_BANDB 0x0856 +#define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 +#define BANDB_DEVICE_ID_USO9ML2_2P 0xBC00 +#define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 +#define BANDB_DEVICE_ID_USO9ML2_4P 0xBC01 +#define BANDB_DEVICE_ID_US9ML2_2 0xAC29 +#define BANDB_DEVICE_ID_US9ML2_4 0xAC30 +#define BANDB_DEVICE_ID_USPTL4_2 0xAC31 +#define BANDB_DEVICE_ID_USPTL4_4 0xAC32 +#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 +#define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02 +#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 +#define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03 +#define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 /* This driver also supports * ATEN UC2324 device using Moschip MCS7840 @@ -184,13 +189,18 @@ static struct usb_device_id moschip_port_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, {} /* terminating entry */ @@ -200,13 +210,18 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, {} /* terminating entry */ @@ -280,12 +295,19 @@ static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg, { struct usb_device *dev = port->serial->dev; int ret = 0; + u8 *buf; + + buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL); + if (!buf) + return -ENOMEM; ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, - MCS_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH, + MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); + *val = buf[0]; dbg("mos7840_get_reg_sync offset is %x, return val %x", reg, *val); - *val = (*val) & 0x00ff; + + kfree(buf); return ret; } @@ -338,6 +360,11 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, struct usb_device *dev = port->serial->dev; int ret = 0; __u16 Wval; + u8 *buf; + + buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL); + if (!buf) + return -ENOMEM; /* dbg("application number is %4x", (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */ @@ -361,9 +388,11 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg, } } ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, - MCS_RD_RTYPE, Wval, reg, val, VENDOR_READ_LENGTH, + MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT); - *val = (*val) & 0x00ff; + *val = buf[0]; + + kfree(buf); return ret; } @@ -714,7 +743,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) mos7840_port = urb->context; if (!mos7840_port) { dbg("%s", "NULL mos7840_port pointer"); - mos7840_port->read_urb_busy = false; return; } @@ -2259,6 +2287,9 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file, case TIOCGICOUNT: cnow = mos7840_port->icount; smp_rmb(); + + memset(&icount, 0, sizeof(struct serial_icounter_struct)); + icount.cts = cnow.cts; icount.dsr = cnow.dsr; icount.rng = cnow.rng; diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 5ceaa4c6be09..061a08385673 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c @@ -24,6 +24,7 @@ static int debug; static struct usb_device_id id_table [] = { { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ + { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 80f59b6350cb..db7cf0866046 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -99,8 +99,8 @@ static void opticon_bulk_callback(struct urb *urb) available_room = tty_buffer_request_room(tty, data_length); if (available_room) { - tty_insert_flip_string(tty, data, - available_room); + tty_insert_flip_string(tty, data + 2, + data_length); tty_flip_buffer_push(tty); } tty_kref_put(tty); @@ -134,7 +134,7 @@ static void opticon_bulk_callback(struct urb *urb) priv->bulk_address), priv->bulk_in_buffer, priv->buffer_size, opticon_bulk_callback, priv); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); + result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); if (result) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2199e1caa8e1..774814d7a2c9 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -165,7 +165,10 @@ static int option_resume(struct usb_serial *serial); #define HUAWEI_PRODUCT_E143D 0x143D #define HUAWEI_PRODUCT_E143E 0x143E #define HUAWEI_PRODUCT_E143F 0x143F +#define HUAWEI_PRODUCT_K4505 0x1464 +#define HUAWEI_PRODUCT_K3765 0x1465 #define HUAWEI_PRODUCT_E14AC 0x14AC +#define HUAWEI_PRODUCT_ETS1220 0x1803 #define QUANTA_VENDOR_ID 0x0408 #define QUANTA_PRODUCT_Q101 0xEA02 @@ -226,6 +229,7 @@ static int option_resume(struct usb_serial *serial); #define AMOI_PRODUCT_H01 0x0800 #define AMOI_PRODUCT_H01A 0x7002 #define AMOI_PRODUCT_H02 0x0802 +#define AMOI_PRODUCT_SKYPEPHONE_S2 0x0407 #define DELL_VENDOR_ID 0x413C @@ -288,7 +292,9 @@ static int option_resume(struct usb_serial *serial); #define QUALCOMM_VENDOR_ID 0x05C6 -#define MAXON_VENDOR_ID 0x16d8 +#define CMOTECH_VENDOR_ID 0x16d8 +#define CMOTECH_PRODUCT_6008 0x6008 +#define CMOTECH_PRODUCT_6280 0x6280 #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 @@ -315,6 +321,7 @@ static int option_resume(struct usb_serial *serial); #define QISDA_PRODUCT_H21_4512 0x4512 #define QISDA_PRODUCT_H21_4523 0x4523 #define QISDA_PRODUCT_H20_4515 0x4515 +#define QISDA_PRODUCT_H20_4518 0x4518 #define QISDA_PRODUCT_H20_4519 0x4519 /* TLAYTECH PRODUCTS */ @@ -333,6 +340,24 @@ static int option_resume(struct usb_serial *serial); #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S 0x0000 +#define PIRELLI_VENDOR_ID 0x1266 +#define PIRELLI_PRODUCT_C100_1 0x1002 +#define PIRELLI_PRODUCT_C100_2 0x1003 +#define PIRELLI_PRODUCT_1004 0x1004 +#define PIRELLI_PRODUCT_1005 0x1005 +#define PIRELLI_PRODUCT_1006 0x1006 +#define PIRELLI_PRODUCT_1007 0x1007 +#define PIRELLI_PRODUCT_1008 0x1008 +#define PIRELLI_PRODUCT_1009 0x1009 +#define PIRELLI_PRODUCT_100A 0x100a +#define PIRELLI_PRODUCT_100B 0x100b +#define PIRELLI_PRODUCT_100C 0x100c +#define PIRELLI_PRODUCT_100D 0x100d +#define PIRELLI_PRODUCT_100E 0x100e +#define PIRELLI_PRODUCT_100F 0x100f +#define PIRELLI_PRODUCT_1011 0x1011 +#define PIRELLI_PRODUCT_1012 0x1012 + /* Airplus products */ #define AIRPLUS_VENDOR_ID 0x1011 #define AIRPLUS_PRODUCT_MCD650 0x3198 @@ -349,6 +374,16 @@ static int option_resume(struct usb_serial *serial); #define THINKWILL_VENDOR_ID 0x19f5 #define THINKWILL_PRODUCT_ID 0x9909 +#define CINTERION_VENDOR_ID 0x0681 + +/* Olivetti products */ +#define OLIVETTI_VENDOR_ID 0x0b3c +#define OLIVETTI_PRODUCT_OLICARD100 0xc000 + +/* Celot products */ +#define CELOT_VENDOR_ID 0x211f +#define CELOT_PRODUCT_CT680M 0x6801 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(THINKWILL_VENDOR_ID,THINKWILL_PRODUCT_ID)}, @@ -447,7 +482,10 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ @@ -483,6 +521,7 @@ static struct usb_device_id option_ids[] = { { 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(AMOI_VENDOR_ID, AMOI_PRODUCT_SKYPEPHONE_S2) }, { 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 */ @@ -526,7 +565,8 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ @@ -548,6 +588,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff) }, @@ -559,38 +600,52 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, + /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff) }, + /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0079, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0082, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0083, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0087, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, @@ -624,6 +679,180 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1060, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1061, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1062, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1063, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1064, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1065, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1066, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1067, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1068, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1069, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1070, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1071, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1072, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1073, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1074, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1075, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1076, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1077, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1078, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1079, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1080, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1081, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1082, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1083, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1084, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1085, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1086, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1087, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1088, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1089, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1090, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1091, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1092, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1093, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1094, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1095, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1096, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1097, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1098, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1099, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1100, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1101, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1102, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1103, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1104, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1105, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1106, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1107, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1108, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1109, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1110, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1111, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1112, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1113, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1114, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1115, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1116, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1117, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1118, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1119, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1120, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1121, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1122, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1123, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1124, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1125, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1126, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1127, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1128, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1129, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1130, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1131, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1132, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1133, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1134, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1135, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1136, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1137, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1138, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1139, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1140, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1141, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1142, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1143, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1144, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1145, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1146, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1147, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1148, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1149, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1150, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1151, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1152, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1153, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1154, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1155, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1156, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1157, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1158, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1159, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1160, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1161, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1162, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1163, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1164, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1165, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1166, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1167, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1168, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1260, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1261, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1262, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1263, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1264, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1265, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1266, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1274, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1275, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1276, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1277, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1278, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1279, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1280, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1281, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1282, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1283, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1284, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1285, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1286, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1287, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1288, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1289, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1290, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1291, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1292, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1293, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1294, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1295, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1296, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1297, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, @@ -632,6 +861,8 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, @@ -642,6 +873,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, + { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4518) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ @@ -653,6 +885,26 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, + /* Pirelli */ + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, + { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -775,12 +1027,26 @@ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct option_intf_private *data; + /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) return -ENODEV; + /* Bandrich modem and AT command interface is 0xff */ + if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || + serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && + serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) + return -ENODEV; + + /* Don't bind network interfaces on Huawei K3765 & K4505 */ + if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID && + (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 || + serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) && + serial->interface->cur_altsetting->desc.bInterfaceNumber == 1) + return -ENODEV; + data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 9ec1a49e2362..ecb17081e003 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -95,6 +95,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, + { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, { } /* Terminating entry */ diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index d640dc951568..01bc64b3eef3 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -127,6 +127,10 @@ #define CRESSI_VENDOR_ID 0x04b8 #define CRESSI_EDY_PRODUCT_ID 0x0521 +/* Zeagle dive computer interface */ +#define ZEAGLE_VENDOR_ID 0x04b8 +#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522 + /* Sony, USB data cable for CMD-Jxx mobile phones */ #define SONY_VENDOR_ID 0x054c #define SONY_QN3USB_PRODUCT_ID 0x0437 diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 7528b8d57f1c..8ab4ab2231dd 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -47,6 +47,35 @@ static struct usb_device_id id_table[] = { {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ + {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ + {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ + {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ + {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ + {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ + {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ + {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ + {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ + {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ + {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ + {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ + {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ + {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ + {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ + {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ + {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ + {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ + {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ + {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 5019325ba25d..328578bdb455 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -195,6 +195,7 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = { static struct usb_device_id id_table [] = { { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ + { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */ { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ @@ -209,6 +210,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ + { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U */ /* Sierra Wireless C597 */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, /* Sierra Wireless T598 */ @@ -567,14 +569,17 @@ static void sierra_indat_callback(struct urb *urb) } else { if (urb->actual_length) { tty = tty_port_tty_get(&port->port); + if (tty) { + tty_buffer_request_room(tty, + urb->actual_length); + tty_insert_flip_string(tty, data, + urb->actual_length); + tty_flip_buffer_push(tty); - tty_buffer_request_room(tty, urb->actual_length); - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - - tty_kref_put(tty); - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); + tty_kref_put(tty); + usb_serial_debug_data(debug, &port->dev, + __func__, urb->actual_length, data); + } } else { dev_dbg(&port->dev, "%s: empty read urb" " received\n", __func__); diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index ad1f9232292d..c14087018887 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -249,6 +249,7 @@ static struct usb_serial_driver clie_3_5_device = { .throttle = visor_throttle, .unthrottle = visor_unthrottle, .attach = clie_3_5_startup, + .release = visor_release, .write = visor_write, .write_room = visor_write_room, .write_bulk_callback = visor_write_bulk_callback, diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index 4395c4100ec2..38e3c3aa05a1 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -120,7 +120,7 @@ static ssize_t show_truinst(struct device *dev, struct device_attribute *attr, } return result; } -static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL); +static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL); int sierra_ms_init(struct us_data *us) { diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c932f9053188..72150021cc79 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1147,8 +1147,8 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, 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 + * These devices (wrongly) have a vendor-specific device descriptor. + * These entries are needed so usb-storage can bind to their mass-storage * interface as an interface driver */ UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, "Option", @@ -1156,6 +1156,90 @@ UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, 0 ), +UNUSUAL_DEV( 0x0af0, 0x7701, 0x0000, 0x0000, + "Option", + "GI 0451 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7706, 0x0000, 0x0000, + "Option", + "GI 0451 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7901, 0x0000, 0x0000, + "Option", + "GI 0452 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7A01, 0x0000, 0x0000, + "Option", + "GI 0461 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7A05, 0x0000, 0x0000, + "Option", + "GI 0461 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x8300, 0x0000, 0x0000, + "Option", + "GI 033x SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x8302, 0x0000, 0x0000, + "Option", + "GI 033x SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0000, + "Option", + "GI 033x SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000, + "Option", + "GI 070x SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd057, 0x0000, 0x0000, + "Option", + "GI 1505 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd058, 0x0000, 0x0000, + "Option", + "GI 1509 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd157, 0x0000, 0x0000, + "Option", + "GI 1515 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd257, 0x0000, 0x0000, + "Option", + "GI 1215 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd357, 0x0000, 0x0000, + "Option", + "GI 1505 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + /* Reported by Ben Efros */ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, "Seagate", @@ -1774,6 +1858,21 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Hans de Goede + * These Appotech controllers are found in Picture Frames, they provide a + * (buggy) emulation of a cdrom drive which contains the windows software + * Uploading of pictures happens over the corresponding /dev/sg device. */ +UNUSUAL_DEV( 0x1908, 0x1315, 0x0000, 0x0000, + "BUILDWIN", + "Photo Frame", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_BAD_SENSE ), +UNUSUAL_DEV( 0x1908, 0x1320, 0x0000, 0x0000, + "BUILDWIN", + "Photo Frame", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_BAD_SENSE ), + UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, "ST", "2A", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c old mode 100644 new mode 100755 index 7c8f64d842f2..33197fa22715 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -74,7 +74,7 @@ MODULE_AUTHOR("Matthew Dharm "); MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); MODULE_LICENSE("GPL"); -static unsigned int delay_use = 1; +static unsigned int delay_use = 5; module_param(delay_use, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 6615ac7fa60a..5e20e6ec1719 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -196,12 +196,12 @@ static int backlight_suspend(struct device *dev, pm_message_t state) { struct backlight_device *bd = to_backlight_device(dev); - if (bd->ops->options & BL_CORE_SUSPENDRESUME) { - mutex_lock(&bd->ops_lock); + mutex_lock(&bd->ops_lock); + if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { bd->props.state |= BL_CORE_SUSPENDED; backlight_update_status(bd); - mutex_unlock(&bd->ops_lock); } + mutex_unlock(&bd->ops_lock); return 0; } @@ -210,12 +210,12 @@ static int backlight_resume(struct device *dev) { struct backlight_device *bd = to_backlight_device(dev); - if (bd->ops->options & BL_CORE_SUSPENDRESUME) { - mutex_lock(&bd->ops_lock); + mutex_lock(&bd->ops_lock); + if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { bd->props.state &= ~BL_CORE_SUSPENDED; backlight_update_status(bd); - mutex_unlock(&bd->ops_lock); } + mutex_unlock(&bd->ops_lock); return 0; } diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 9edb8d7c295f..73ab600efbf8 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -137,6 +137,51 @@ static int mbp_dmi_match(const struct dmi_system_id *id) } static const struct dmi_system_id __initdata mbp_device_table[] = { + { + .callback = mbp_dmi_match, + .ident = "MacBook 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 2,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 3,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 4,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 4,2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"), + }, + .driver_data = (void *)&intel_chipset_data, + }, { .callback = mbp_dmi_match, .ident = "MacBookPro 3,1", diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 5cc36cfbf07b..2c72a7ca7366 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c @@ -515,9 +515,9 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) fbinfo->fbops = &bfin_t350mcqb_fb_ops; fbinfo->flags = FBINFO_FLAG_DEFAULT; - info->fb_buffer = - dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle, - GFP_KERNEL); + info->fb_buffer = dma_alloc_coherent(NULL, fbinfo->fix.smem_len + + ACTIVE_VIDEO_MEM_OFFSET, + &info->dma_handle, GFP_KERNEL); if (NULL == info->fb_buffer) { printk(KERN_ERR DRIVER_NAME @@ -587,8 +587,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) out6: fb_dealloc_cmap(&fbinfo->cmap); out4: - dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, - info->dma_handle); + dma_free_coherent(NULL, fbinfo->fix.smem_len + ACTIVE_VIDEO_MEM_OFFSET, + info->fb_buffer, info->dma_handle); out3: framebuffer_release(fbinfo); out2: @@ -611,8 +611,9 @@ static int __devexit bfin_t350mcqb_remove(struct platform_device *pdev) free_irq(info->irq, info); if (info->fb_buffer != NULL) - dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, - info->dma_handle); + dma_free_coherent(NULL, fbinfo->fix.smem_len + + ACTIVE_VIDEO_MEM_OFFSET, info->fb_buffer, + info->dma_handle); fb_dealloc_cmap(&fbinfo->cmap); diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index eb12182b2059..c0a446560ab4 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c @@ -13,7 +13,7 @@ #include #include #include - +#include #include